题意:输入若干对数,直到文件结束,每对数字有 w s, 找出最长的一个序列满足W[m[1]] < W[m[2]] < ... < W[m[n]] ,S[m[1]] > S[m[2]] > ... > S[m[n]] ,输出长度,且任意输出一条即可。
分析, 先按照w进行排序,然后找最长下降子序列,保存下父节点。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <ctime> using namespace std; const int oo = 1e9; struct Mouse { int w, s; int in; }m[1005]; bool cmp(Mouse a1, Mouse a2) { if(a1.w!=a2.w) return a1.w<a2.w; return a1.s>a2.s; } struct d { int x, pre; }dp[1005]; void print(int index) { if(index==-1) { return ; } print(dp[index].pre); printf("%d ", m[index].in+1); } int main() { int k = 0; while(~scanf("%d%d", &m[k].w, &m[k].s)) { m[k].in = k; k++; } sort(m, m+k, cmp); for(int i=0; i<k; i++) { dp[i].pre = -1; dp[i].x = 1; } int ans = 0; int index; for(int i=0; i<k; i++) { for(int j=0; j<i; j++) { if(m[j].w<m[i].w && m[j].s>m[i].s) { if(dp[i].x<dp[j].x+1) { dp[i].x = dp[j].x + 1; dp[i].pre = j; } } } if(ans<dp[i].x) { ans = dp[i].x; index = i; } } printf("%d ", ans); print(index); return 0; }