码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-1024Max Sum Plus Plus(最大m段子序列和-DP)

时间:2020-07-08 00:58:59      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:序列   NPU   include   max   code   ons   algorithm   最大值   子序列   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024

题目大意:给m 和n个数,将n个数分为m段,不交叉,求m段和的最大值。

Sample Input

1 3 1 2 3
2 6 -1 4 -2 3 -2 3

Sample Output

6
8

emmm,先想容易的,我们应该很容易想到设置状态$dp[i][j]$表示在第$j$个字段末尾分为$i$段的最大值,那么则有$dp[i][j]=max(dp[i][j-1]+a[j],pre[i-1][j-1]+a[j])$也就是该数字要么和之前的数字连接起来也就是$dp[i][j-1]+a[j]$,要么自成一段,就是$pre[i-1][j-1]+a[j]$,其中$pre[i][j]$表示在$j$之前分为$i$段的最大值是多少。

那么我们看到,实际上用到的只有上一段,也就是说我们完全可以直接将其化为滚动数组。那么代码也就出来了

以下是AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

typedef long long ll;
const int mac=1e6+10;
const ll inf=1e15+10;

int a[mac];
ll dp[mac],pre[mac];

int main(int argc, char const *argv[])
{
    int m,n;
    while (~scanf ("%d%d",&m,&n)){
        for (int i=1; i<=n; i++)
            scanf ("%d",&a[i]);
        memset(dp,0,sizeof dp);
        memset(pre,0,sizeof pre);
        dp[0]=-inf;
        ll mi;
        for (int i=1; i<=m; i++){
            mi=-inf;
            for (int j=i; j<=n; j++){
                dp[j]=max(dp[j-1]+a[j],pre[j-1]+a[j]);
                pre[j-1]=mi;
                mi=max(mi,dp[j]);
            }
        }
        printf("%lld\n",mi);
    }
    return 0;
}

 

HDU-1024Max Sum Plus Plus(最大m段子序列和-DP)

标签:序列   NPU   include   max   code   ons   algorithm   最大值   子序列   

原文地址:https://www.cnblogs.com/lonely-wind-/p/13264330.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!