POJ 1065 Wooden Sticks 【贪心】

来源:互联网 发布:数据库死锁解决 编辑:程序博客网 时间:2024/05/16 06:14

题目链接

题意

给n个整数对,定义数对间的大于关系是(w1,l1)(w2,l2)w1w2andl1l2,求用这些数对最少能组成几组非递减序列

分析

LIS的变形,但考虑到原来给的这些数对并没有顺序,可以随便选择,因此没有必要用DP求LIS。可以倒序排序(先按第一个数排序,再按第二个数排序)后,贪心,即从左到右遍历,选择当前还没有被选择的数对中的最小的一个,则它一定是某个序列的最后一个元素,然后从它开始向右遍历,只要是比它大的数对都标记访问,并且下一个以这个数对为比较依据,这样遍历结束后就选出了一个非递减序列。

AC代码

//POJ 1065 Wooden Sticks//AC 2016-8-8 12:00:46//Greedy#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cctype>#include <cstdlib>#include <cstring>#include <vector>#include <set>#include <string>#include <map>#include <queue>#include <deque>#include <list>#include <sstream>#include <stack>using namespace std;#define cls(x) memset(x,0,sizeof x)#define inf(x) memset(x,0x3f,sizeof x)#define neg(x) memset(x,-1,sizeof x)#define ninf(x) memset(x,0xc0,sizeof x)#define st0(x) memset(x,false,sizeof x)#define st1(x) memset(x,true,sizeof x)#define INF 0x3f3f3f3f#define lowbit(x) x&(-x)#define input(x) scanf("%d",&(x))#define bug cout<<"here"<<endl;//#define debugpair<int,int> sticks[5050];int visit[5050];inline bool smaller(int a,int b){    return (sticks[a].first<=sticks[b].first)&&(sticks[a].second<=sticks[b].second);}int main(){    #ifdef debug        freopen("E:\\Documents\\code\\input.txt","r",stdin);        freopen("E:\\Documents\\code\\output.txt","w",stdout);    #endif    int T,n;    input(T);    while(T--)    {        input(n);        for(int i=0;i<n;++i)        {            input(sticks[i].first);            input(sticks[i].second);        }        sort(sticks,sticks+n);        int res=0;        cls(visit);        for(int i=0;i<n;++i)        {            if(visit[i]) continue;            visit[i]=1;            int cur=i;            for(int j=i+1;j<n;++j)            {                if(smaller(cur,j)&&!visit[j])                {                    cur=j;                    visit[cur]=1;                }            }            ++res;        }        printf("%d\n",res);    }    return 0;}
0 0
原创粉丝点击