POJ-1065 Wooden Sticks 动态规划之求下降子序列的个数。

有N根木棍等待处理。机器在处理第一根木棍时需要准备1分钟,此后遇到长宽都不大于前一根木棍的木棍就不需要时间准备,反之则需要1分钟重新准备。比如木棍按照(3,3)、(1,3)、(1,4)、(2,3)的顺序进入,共需要准备3分钟
Input
第一行是T,表示测试数据个数。测试数据的第一行是N(1 <= N <= 5000)此后一行是 l1 , w1 , l2 , w2 ,…, ln , wn……长宽都小于10000
Output
每个一行,表示最短准备时间
Sample Input
3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1
Sample Output
2
1
3

中文题意如上,思路比较简单,首先要排序,把长宽都是从大到小排序,直接用一个数组维护一个序列就可以,如果对于每个木棒,如果能够放到某个序列后面就放上去,如果不能就再增加一个序列。最后序列的个数,就是需要花费的时间。注意每次我们都要把木棒放到第一个可以放的序列。因为后面的木棒肯定是比当前木棒的长或宽小的,如果把当前的木棒放到后面的序列就不符合贪心的策略了。

代码如下:

#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;
typedef pair<int,int> P;
const int MAX = 5010;
P p[MAX],need[MAX];
int N;
bool cmp(P A,P B){
    if(A.first == B.first)
        return A.second > B.second;
    else
        return A.first > B.first;
}
int solve(){
    int top = 1;
    need[top] = p[1];
    for(int i=2;i<=N;++i){
        bool isfind = false;
        for(int j=1;j<=top;++j){
            if(p[i].first <= need[j].first && p[i].second <= need[j].second){
             //   printf("%d,%d,%d\n",j,p[i].first,p[i].second);
                need[j] = p[i];
                isfind = true;
                break;//这里不能少。
            }
        }
        if(!isfind){
            need[++top] = p[i];
 //           printf("%d,%d\n",p[i].first,p[i].second);
        }
    }
    return top;
}
int main(void){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        for(int i=1;i<=N;++i){
            scanf("%d%d",&p[i].first,&p[i].second);
        }
        sort(p+1,p+1+N,cmp);
     //   Display();
        printf("%d\n",solve());
    }

    return 0;
}

你可能感兴趣的:(动态规划)