hdu 1231

主题思想:最大连续子序列,最大连续子序列是和最大的连续子序列,
这是一个经典的dp问题。
dp[i] 表示以i结尾的连续子序列的和
对于第i个数字,或者选择加入前面的序列,此时dp[i]=dp[i-1]+a[i],或者本身作为一个单独的序列,此时dp[i]=a[i]。

dp[i]=max(a[i],dp[i-1]+a[i])

即,如果dp[i-1]+a[i]>a[i] 则选择a[i]加入以前的序列。否则自己成为一个单独的序列。 移项得dp[i-1]>0

最后遍历一遍,找出最大的连续子序列和。

如果需要记录子序列的开头位置,则需要新开一个数组s,s[i] 用来表示以i个元素结尾的,连续子序列的开头位置,
当dp[i-1]>0时 ,dp[i]=dp[i-1]+a[i] ,s[i]=s[i-1]
当dp[i-1]<=0 时,dp[i]=a[i] s[i]=i

AC代码:

#include <iostream>
#include<cstring>
#include<cstdio>

using namespace std;

const int maxn=10005;

int dp[maxn];  //dp[i] menas the max sum of sequence end with i

int s[maxn];  // s[i] remember the start index i of the sequence stands by  dp[i]


int a[maxn];
int main()
{
   int k;
   while(scanf("%d",&k)!=EOF){

        if(k==0) break;
        int m=0;
        for(int i=1;i<=k;i++){

            scanf("%d",&a[i]);
            if(a[i]<0)m++;
        }

        if(m==k){

            printf("0 %d %d\n",a[1],a[k]);
            continue;
        }

        dp[1]=a[1];
        int mx=dp[1];
        for(int i=2;i<=k;i++){

            if(dp[i-1]>0){
                dp[i]=dp[i-1]+a[i];
                s[i]=s[i-1];
            }else{
                dp[i]=a[i];
                s[i]=i;
            }
        }
        int start=1,e=1;
        for(int i=2;i<=k;i++){

            if(dp[i]>mx){
                mx=dp[i];
                e=i;
                start=s[i];
            }
        }

        printf("%d %d %d\n",mx,a[start],a[e]);
   }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值