hdu1231最大连续子序列dp

http://acm.hdu.edu.cn/showproblem.php?pid=1231

WA的代码,我还不知道WA在哪里。

#include
using namespace std;
#include

long long num[10005];


struct Node
{
    int start,end;
    long long sum;
}dp[10005];

int main()
{
    int k;
    while(scanf("%d",&k)!=EOF&&k)
    {
        int i;
        for(i=1;i<=k;i++)
        scanf("%lld",&num[i]);
        for(i=0;i<=k;i++)
            dp[i].sum=-0x3f3f3f;

        for(i=1;i<=k;i++)
        {
            if(num[i]>dp[i-1].sum+num[i])
            {
                dp[i].start=i;
                dp[i].end=i;
                dp[i].sum=num[i];
            }
            else
            {
                dp[i].start=dp[i-1].start;
                dp[i].end=i;
                dp[i].sum=dp[i-1].sum+num[i];
            }
        }
        dp[1].start=1;
        long long Max=-0x3f3f3f;
        int nnum=0;
        for(i=1;i<=k;i++)
        {
            if(dp[i].sum>Max)
            {
                Max=dp[i].sum;
                nnum=i;
            }
        }

        if(Max<0)
        {
            printf("0 ");
            printf("%d %d\n",num[1],num[k]);
        }
        else 
            printf("%lld %d %lld\n",dp[nnum].sum,num[dp[nnum].start],num[dp[nnum].end]);
        /*long long sum=0;
        long long Max=0;
        for(i=0;i=0)
            Max=max(Max,sum);
            else
            sum=0;
        }
        printf("%lld\n",Max);*/

    }
    return 0;
}

最大连续子序列算是dp中比较简单的情况了吧,有的时候都不需要用到状态转移方程,比如这个题这种的,就是只求正的最大连续子序列,如果抛开需要输出这个最大子序列的头尾的话,就只需要设一个sum,一个max,如果sum>0,就加上新的,然后如果sum<0了,就无论如何sum都是一个“拖累”,所以sum变成num【i】,但是这样不能求负数的最大连续子序列。
其实dp状态方程应该是dp[i]=max(dp[i-1]+num[i],num[i]);这个状态转移方程我觉得是比较好理解的了,但是我最开始都没有想到,笨!
为了记录最大连续子序列的头跟尾,我又开了一个结构体,其实感觉不需要这么复杂的,因为在ACM中,感觉更好的方法不是保存,而是更新!
一会儿敲一份大神的代码上来!

#include
using namespace std;

int num[10005],dp[10005];

int main()
{
    int n,i,j,Max,cnt;
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(i=0;i"%d",&num[i]);
        int left,right,flag;
        Max=num[0];
        cnt=0;
        left=right=num[0];
        for(i=0;iif(cnt<0)
            {
                cnt=num[i];
                flag=num[i];
            }
            else
            cnt+=num[i];
            if(cnt>Max)
            {
                Max=cnt;
                left=flag;
                right=num[i];
            }
        }
        if(Max<0)
        {
            printf("0 %d %d\n",num[0],num[n-1]);
            continue;
        }
        printf("%d %d %d\n",Max,left,right);
    }
    return 0;
}

☝我真的好喜欢这个大神的代码风格,简洁干净,特别好!虽然有的时候可能逻辑性比较强然后就看不懂什么的!

你可能感兴趣的:(dp)