【动态规划最大子列和】HDU-1003 Max Sum

在这里插入图片描述

注解

1、用动态规划方法解决最大子列和问题。关键是设置一个dp[]数组,dp[i]表示以i结尾的最大子列和。
如dp[0]表示以0作为结尾的最大子列和,dp[1]表示以1作为结尾的最大子列和。
因此,要求出整个序列的最大子列和,只需要从头到尾遍历dp,找出最大值。这是最原始的最大子列和问题的解法。
2、本题除了要求输出最大和,还要求输出起始位置和终止位置。这就要在dp[]数组的基础上,再增加start[]数组,start[i]表示以i作为结束的最大和的起始位置。
3、动态规划的核心:找出状态转移方程:dp[i] = max(a[i], dp[i-1]+a[i])。
本质就是,如果dp[i-1]>=0,dp[i]就等于dp[i-1]+a[i]。如果dp[i-1]<0,就输出a[i]。
4、一个小的注意点:初始化。题目不保证所有数字都是非负数,因此初始化答案时,应该是用第一个数字初始化。而不能简单用一个负数。因为可能出现所有数字都比这个负数小的情况,这样这个负数就会被误当成最终答案而输出。

代码

#include <iostream>
#include <string.h>

using namespace std;

const int MAX = 100001;
int a[MAX];
int dp[MAX];
int start[MAX];

void process(int len){
    dp[0] = a[0];
    start[0] = 0;
    for(int i=1; i<len; i++){
        if(a[i]>dp[i-1]+a[i]){
            dp[i] = a[i];
            start[i] = i;
        }
        else{
            dp[i] = dp[i-1]+a[i];
            start[i] = start[i-1];
        }
    }
}

int main() {
    int T;
    cin>>T;
    for(int i=1; i<=T; i++) {
        memset(a, 0, sizeof(a));
        memset(dp, 0, sizeof(dp));
        memset(start, 0, sizeof(start));
        int n;
        cin>>n;
        for(int j=0; j<n; j++) {
            cin>>a[j];
        }
        process(n);
        int max = dp[0];
        int ansStart = 1;
        int ansEnd = 1;
        for(int j=1; j<n; j++){
            if(dp[j]>max){
                max = dp[j];
                ansStart = start[j]+1;
                ansEnd = j+1;
            }
        }
        cout<<"Case "<<i<<":"<<endl;
        cout<<max<<" "<<ansStart<<" "<<ansEnd<<endl;
        if(i<T){
            cout<<endl;
        }
    }
    return 0;
}

结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值