HDU 1087 Super Jumping! Jumping! Jumping!最长上升子序列

来源:互联网 发布:莱州网络购物 编辑:程序博客网 时间:2024/05/16 20:29

           一开始题意理解错了,不一定是连续的子序列,只要是升序就可以,理解题意后,以为两个循环枚举起点就可以了,于是写了下段代码:

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int main(){    freopen("in.txt","r",stdin);    int n,num[1010],cur;    long long int sum,maxx;    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=0;i<n;i++)        scanf("%d",&num[i]);        maxx=num[0];        for(int i=0;i<n;i++)        {            sum=num[i];cur=num[i];            for(int j=i+1;j<n;j++)            {                if(num[j]>cur)                {                    sum+=num[j];                    cur=num[j];                }            }            maxx=max(maxx,sum);        }        cout<<maxx<<endl;    }    return 0;}
      WA 后,不知道原因,百度 搜到一组数据,6 1 4 2 3 5 7,很明显我的代码的结果是1+4+5+7=17, 但是 1+2+3+5+7=18是最大的。所以正确思路应该是DP。参考http://www.cnblogs.com/coredux/archive/2012/04/07/2436367.html。这个算是自底向上法吧,某个问题的解依赖于已经求解出来的子问题的解。

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int d[1010],num[1010];int main(){    //freopen("in.txt","r",stdin);    int n,maxx;    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=0; i<n; i++)            scanf("%d",&num[i]);        maxx=-0xffffff;        memset(d,-1,sizeof(d));        for(int i=0; i<n; i++)        {            d[i]=num[i];            for(int j=0; j<i; j++)            {                if(num[j]<num[i])                    if(d[j]+num[i]>d[i])                        d[i]=num[i]+d[j];            }            maxx=max(d[i],maxx);        }        cout<<maxx<<endl;    }    return 0;}