标签:
链接http://acm.hdu.edu.cn/showproblem.php?pid=1160
感觉也是最长上升子序列的变形。。。
这回独立1Y!开心~ 不过在保存路径的时候调了一段时间orzzzzz还是太弱
思路:每个老鼠进行排序,将体重从小到大,若相等再将速度从大到小,保证找出最多的。
定义dp[i]表示以i为末尾的满足条件的最长的序列长度。运用最长上升子序列的那种方法就可以做了,还有要注意的是因为需要将其进行排序,排序后的序号是乱的,所以需要在结构体中加入一个记录原本路径的元素num。要保存路径,还要有一个记录上一个点的元素ls,并赋初值为-1。这样在dp[i]被更新的时候将ls 也更新。。最后记录以哪一个结尾是最大的,从这个节点找上去,并将每个节点都压入栈中,最后将栈内元素一个个输出就可以了。当然用数组也可以的。
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <stack> using namespace std; #define M 1009 #define INF 0x3f3f3f3f int dp[M]; struct node { int w,s,num,ls; }a[M]; int cmp(node a,node b) { if(a.w!=b.w) return a.w < b.w; return a.s > b.s; } int main() { int n = 0; while(scanf("%d %d",&a[n].w,&a[n].s)==2) //while(scanf("%d %d",&a[n].w,&a[n++].s)==2) 不要写成这样 因为这没有顺序 { a[n].num = n; // 保存原本的序号 ,因为要排序所以会破坏 a[n].ls = -1; n++; } sort(a,a+n,cmp); //for(int i = 0;i < n;i++) //printf("debug-- %d %d\n",a[i].w,a[i].s); int ss; int maxn = -INF; for(int i = 0;i < n;i++) { dp[i] = 1; for(int j = 0;j < i;j++) { if(a[i].w>a[j].w && a[i].s<a[j].s) if(dp[i] < dp[j]+1) { dp[i] = dp[j]+1; //int temp = a[i].num; //不要这样写,直接先用排序后的序号,最后统一转化成排序前的,一开始就转换容易混乱。。我就调了好久orzzzzz a[i].ls = j; /*int temp = a[i].num; a[temp].ls = a[j].num;*/ //保存路径还可以写成/**/里的这样。。 } } if(maxn < dp[i]) { maxn = dp[i]; ss = i; /*ss = a[i].num;*/ } } printf("%d\n",maxn); stack<int> st; while(maxn--) { /*st.push(ss);*/ st.push(a[ss].num); //将原本的就是排序之前的序号压入栈 ss = a[ss].ls; } while(!st.empty()) { int temp = st.top(); st.pop(); printf("%d\n",temp+1); } return 0; }
标签:
原文地址:http://blog.csdn.net/liujc_/article/details/45420635