hdu 1160 dp 入门

来源:互联网 发布:聚合信息源码 编辑:程序博客网 时间:2024/05/06 09:14

链接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 0x3f3f3f3fint 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;}


0 0
原创粉丝点击