http://acm.hdu.edu.cn/showproblem.php?pid=1160
题意:现给出老鼠的体重与速度,要求你找出符合要求的最长子序列。
要求是 W[m[1]] < W[m[2]] < ... < W[m[n]](体重) && S[m[1]] > S[m[2]] > ... > S[m[n]] (速度)
分析:有两个变量的话比较不好控制,自然需要先排序。再仔细思考的话,觉得和之前做的防御导弹有点类似,都是求最多能有几个符合条件的。思考到这,能 求出来了,然后再记录路径就可以了
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <map> #include <queue> #include <stack> #include <math.h> using namespace std; #define INF 0x3f3f3f3f const int maxn = 4007; typedef long long LL; int a[maxn], dp[maxn]; struct node { int w, v, sign, h; }s[maxn]; ///按照体重从大到小的顺序排序,若体重相同,按照速度从小到大排序 bool cmp(node p, node q) { if(p.w == q.w) return p.v<q.v; return p.w>q.w; } int main() { int k=1; while(scanf("%d %d", &s[k].w, &s[k].v)!=EOF) { s[k].h = k; s[k].sign = -1; k++; } sort(s+1, s+k+1, cmp); int ans = 0; for(int i=1; i<k; i++) { dp[i] = 1;///不管怎样,它本身都符合条件,也就是它自己1个 for(int j=1; j<i; j++) { if(s[i].w<s[j].w && s[i].v>s[j].v) { if(dp[j]+1>=dp[i]) { dp[i] = dp[j]+1; s[i].sign = j;///标记路径 } } if(dp[i]>dp[ans]) ans = i; } } printf("%d\n", dp[ans]); while(s[ans].sign!=-1) { printf("%d\n", s[ans].h); ans = s[ans].sign; } printf("%d\n", s[ans].h); return 0; }
FatMouse's Speed hdu 1160(动态规划,最长上升子序列+记录路径)
时间: 2024-12-25 13:29:18