A
B
C
水题
D:n个二元组,求最长的一个序列组seq,序列的每一个元素的两个值都分别大于前一个元素
记忆化搜索或者筛选后DP都可以
两种方法

#include<cstdio> #include<cstring> #include<set> #include<string> #include<iostream> #include<map> #include<vector> #include<algorithm> using namespace std; #define DEBUG printf("buuuug\n"); const int maxn = 5010; const int INF = ~0u>>1; int dp[maxn],nxt[maxn]; struct node{ int w,h; }p[maxn]; int n,ans; int dfs(int pos) { if(dp[pos]) return dp[pos]; dp[pos]=1; for(int i=0;i<=n;i++) { if(p[i].w>p[pos].w&&p[i].h>p[pos].h) { if(dfs(i)+1>dp[pos]) { nxt[pos]=i; dp[pos]=dp[i]+1; } } } return dp[pos]; } int main() { int i,j,k; scanf("%d",&n); for(i=0;i<=n;i++) scanf("%d%d",&p[i].w,&p[i].h); memset(nxt,-1,sizeof(nxt)); dfs(0); printf("%d\n",dp[0]-1); for(i=nxt[0];i!=-1;i=nxt[i]) { printf("%d ",i); } puts(""); return 0; }

#include<cstdio> #include<cstring> #include<set> #include<string> #include<iostream> #include<map> #include<vector> #include<algorithm> using namespace std; #define DEBUG printf("buuuug\n"); const int maxn = 5010; const int INF = ~0u>>1; int dp[maxn],fa[maxn],ne[maxn]; int a[maxn]; struct node{ int w,h; int id; }p[maxn]; int cmp(node a,node b) { if(a.w!=b.w) return a.w<b.w; return a.h<b.h; } int n,ans; int main() { int i,j,k,w,h; scanf("%d",&n); scanf("%d%d",&w,&h); int tot=0; for(i=1;i<=n;i++) { scanf("%d%d",&p[i].w,&p[i].h); if(p[i].w>w&&p[i].h>h) { p[++tot]=p[i]; p[tot].id=i; } } if(tot==0) { puts("0"); return 0; } p[0].id=0;dp[0]=1; sort(p+1,p+tot+1,cmp); memset(fa,-1,sizeof(fa)); int end; for(i=1;i<=tot;i++) { dp[i]=1; for(j=1;j<i;j++) { if(p[j].w<p[i].w && p[j].h<p[i].h && dp[j]+1>dp[i]) { dp[i]=dp[j]+1;fa[i]=j; } } if(dp[i]>ans) ans=dp[i],end=i; } printf("%d\n",ans);int tmp=ans; while(end!=-1) { a[tmp--]=p[end].id; end=fa[end]; } for(i=1;i<=ans;i++) printf("%d ",a[i]); //scanf("%d",&n); return 0; } /* 6 1 1 900000 900000 902400 902400 901200 901200 903600 903600 906000 906000 904800 904800 */