codeforces 4D
题意:给定n和信封和一个w 和 h,要求以下的信封选取最多的,然后 wi 必须比 w 大并递增,hi 比 h 大也递增,问最多的信封数和哪些,按照顺序输出
题解:按照w递增排序后,求h的最长上升子序列并输出路径
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define eps 1e-4 #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define ll long long #define LL long long const int MAXN = 1e5 + 5; const int mod = 998244353; struct node{ int w,h; int id; }a[MAXN]; bool cmp(node a,node b) { if(a.w != b.w) return a.w < b.w; return a.h < b.h; } int dp[MAXN]; int path[MAXN]; void print(int n) { if(path[n] == -1) { printf("%d ",a[n].id); return ; } else { print(path[n]); printf("%d ",a[n].id); } } int main() { int n, w, h; cin >> n >> w >> h; int pos = 0; for(int i = 1; i <= n; i++) { int w1,h1; cin >> w1 >> h1; if(w1 > w && h1 > h) { a[pos].w = w1; a[pos].h = h1; a[pos].id = i; pos++; } } if(pos == 0) { cout << 0 << endl; return 0; } sort(a, a + pos, cmp); for(int i = 0; i < pos; i++) { dp[i] = 1; path[i] = i; } memset(path, -1, sizeof path); int maxlen = 1,biao = 0; for(int i = 0; i < pos; i++) { for(int j = 0; j < i; j++) { if(a[j].h < a[i].h && a[j].w < a[i].w && dp[i] < (dp[j] + 1)) { dp[i] = dp[j] + 1; if(dp[i] > maxlen) maxlen = dp[i]; path[i] = j; } } } int tmp,cmp = 0; for(int i = 0; i < n; i++) { if(dp[i] > cmp) { cmp = dp[i]; tmp = i; } } cout << maxlen << endl; // debug(tmp); print(tmp); }