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;
}