题意:给你一系列个w,s。要你找到最长的n使得
W[m[1]] < W[m[2]] < ... < W[m[n]]
and
S[m[1]] > S[m[2]] > ... > S[m[n]]
即在这n个w,s中满足w[i]<w[j]&&s[i]>s[j],要求:体重严格递增,速度严格递减,原始顺序不定
首先将s从大到小排序,即顺数固定后转化为最长上升子序列问题.
案例:
6008 1300 6000 2100 500 2000 1000 4000 1100 3000 6000 2000 8000 1400 6000 1200 2000 1900
Sample Output
4 4 5 9 7
1000 4000
1100 3000
2000 1900
8000 1400
#include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #include <stack> #include<algorithm> #include<set> using namespace std; #define INF 999999999 #define eps 1e-4 #define LL __int64 #define maxn 26 #define mol 1000000007 #define N 505 #define M 50010 struct node { int v,s,num; }p[1105]; int pre[1105];//路径保存pre[i]表示 i 的前一个数 int cmp(node a,node b) { return a.s>b.s; } void out(int k)//递归输出 { if(pre[k]==-1) { printf("%d ",k); return; } out(pre[k]); printf("%d ",k); } int main() { int n=1,dp[1105]; while(~scanf("%d%d",&p[n].v,&p[n].s)) { p[n].num=n; n++; } sort(p+1,p+n+1,cmp); for(int i=1;i<n;i++) dp[i]=0,pre[i]=-1; dp[1]=1; pre[p[1].num]=-1; int ans=1,k=1; for(int i=2;i<n;i++) { int maxx=0,index=-1; for(int j=1;j<i;j++) { if(p[j].s>p[i].s&&p[j].v<p[i].v) { if(dp[j]>maxx) { maxx=dp[j]; index=p[j].num; } } } dp[i]=maxx+1; pre[p[i].num]=index; if(dp[i]>ans) { ans=dp[i]; k=p[i].num; } } printf("%d ",ans); out(k); return 0; } /* 6008 1300 6000 2100 500 2000 1000 4000 1100 3000 6000 2000 8000 1400 6000 1200 2000 1900 */