UVA 10131 Is Bigger Smarter?

来源:互联网 发布:林建岳王祖贤 知乎 编辑:程序博客网 时间:2024/06/03 00:56

大意不再赘述。

思路:最长上升子序列的变形。可以这样列出状态转移方程:d[i] = max(d[j]+1)(1 <= j <= i-1 && A[i].w > A[j].w && A[i].v <A[j].v)
即d[i]表示以i为终点重量上升但速度下降的最长序列,具体实现只要加一个限制条件即可,如何打印路径呢?我们可以人为地添加一个pre数组记录前驱,然后保存最大的d[i]时,调用递归程序递归打印路径即可,注意输入格式。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <algorithm>using namespace std;const int MAXN = 10010;struct node{int w, v;int id;}A[MAXN];int tot;int d[MAXN];int pre[MAXN];int cmp(const node a, const node b){return a.w < b.w;}void init(){tot = 1;memset(pre, -1, sizeof(pre));}void print_ans(int x){int y = pre[x];if(y == -1){printf("%d\n", A[x].id);return ;}print_ans(y);printf("%d\n", A[x].id);}void dp(){int ans = 0, index = 0;for(int i = 1; i <= tot; i++){d[i] = 1;for(int j = 1; j <= i-1; j++) if(A[i].w > A[j].w && A[i].v < A[j].v){if(d[i] < d[j]+1){d[i] = d[j]+1;pre[i] = j;}}if(ans < d[i]){ans = d[i];index = i;}}printf("%d\n", ans);print_ans(index);}int main(){init();while(~scanf("%d%d", &A[tot].w, &A[tot].v)){A[tot].id = tot;tot++;}--tot;sort(A+1, A+1+tot, cmp);dp();return 0;}