寒假集訓 Day2 F Wooden Sticks HDU1051:木條排序

1.12F題 HDU-1051

題目大意:

n個具有l、w權值的木條,找出儘可能多的上升至序列,木條 i 比木條 j 大當且僅當 li > lj 並且 wi > wj時。

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

解題思路:

1.開始的時候我想對所有的木條進行l 、w的拓撲排序, 然後找到極小的木條便加1,知道所有木條都用完。但是在如圖排序下會有bug。
這裏寫圖片描述

2.講解的正確解題思路:對l排序,這樣整個序列滿足l≤l​′,然後遍歷這個序列,如果還滿足w≤w​′​​,把這個木棍的下標記下來,去找下一個滿足條件的木棍,這樣找下去就找到第一個子序列。再去找剩下的,發現我們不知道哪些是找過的,可以給木棍加一個 used 狀態,0 爲未訪問,1 爲訪問過,每次找子序列先找到一個未訪問過的木棍,把 res 加 1 ,然後對於這個序列我貪心的去找下一根木棍並把它的 used 記爲 1 。全部木棍被標爲 1 的時候也就找完了。

AC代碼

#include<cstdio>
#include<iostream>
#include<queue>
#include<string>
#include<cmath>
#include<algorithm>
#include<limits.h>
#define rep(i,l,p) for(int i=l; i<=p; i++)
#define drep(i,p,l) for(int i=p; i>=l; i--)
using namespace std;
const int maxN = 5005;
typedef pair<int, int> P;
int n;
int T;
bool used[maxN]; 
P wood[maxN];
int main(){
//  freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);

    scanf("%d",&T);
    rep(z,1,T){
        scanf("%d",&n);
        fill(used,used+maxN,false);
        rep(i,1,n){
            scanf("%d%d",&wood[i].first,&wood[i].second);
        }

        sort(wood+1,wood+1+n);

        int ans = 0;
        int usednum = 0;
        while(usednum < n){
            ans++;
            int w = INT_MIN; 
            rep(i,1,n){
                if ( used[i] ) continue;
                if ( wood[i].second >= w ){
                    w = wood[i].second;
                    used[i] = true; 
                    usednum++;
                } 
            }
        }

        printf("%d\n",ans);     

    }   
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章