@Acqua
2019-01-17T13:23:11.000000Z
字数 932
阅读 883
动态规划
给定一个二元集合,求其中元素所构成的使递增且递减的最长序列。
最长上升子序列的路径记录。
1. 链表(实现简单)
2. 倒推
// La Pluie#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N = 1e3 + 5;struct node{int m, v, id;} p[N];bool pluie(node x, node y){return x. m == y. m ? x. v < y. v : x. m > y. m;}int f[N], adv[N];int main(){// freopen("testdata.txt", "r", stdin);printf("%d", adv[1000]);int n = 1;while(scanf("%d%d", &p[n]. m, &p[n]. v)!=EOF){p[n]. id = n; // 此处不可简写为 p[n]. id = n++,因为赋值语句从右至左执行,会出错n++;}n--; sort(p + 1, p + n + 1, pluie);p[0] = (node){1e9, 0, 0};int root = 0;for(int i = 1; i <= n; i++){f[i] = 0;for(int j = 0; j < i; j++){if(p[i]. m < p[j]. m && p[i]. v > p[j]. v){if(f[i] <= f[j] + 1){f[i] = f[j] + 1;adv[i] = j;if(f[root] < f[i]) root = i;}}}}printf("%d\n", f[root]);while(adv[root]){printf("%d\n", p[root]. id);root = adv[root];}printf("%d", p[root]. id);return 0;}