HDU1024 Max Sum Plus Plus

HDU1024   Max Sum Plus Plus

题意

给n个数,求取出m段(连续),最大和为多少

分析

错解:一开始考虑进去连续取这个条件,写了错的转移

定义:dp[i][j]:前 j 个数取出 i 段的最大和

决策:第 j 个数是和 j-1 一组, 还是单独成组

转移:dp[i][j] = max( dp[i][j-1] + a[j],dp[i-1][k] + a[j] ) ( i-1 <= k <= j-1)

直接写的时间复杂度(m*n^2)显然超时,从状态转移方程可以看出dp[i][j] 需要上一层 i-1 中 k ( i-1 <= k <= j-1)这些中最大值,开一个数组记录一下就好,这个数组用了一个小技巧“ 滞后 ”传递

优化:由于我们已经记录下了dp[i-1][k] ( i-1 <= k <= j-1)的最大值,所以直接一个一维数组即可

边界处理:直接让dp数组为0即可

时间复杂度O(m*n)

#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAXN 1000000
#define INF 0x7fffffff
int dp[MAXN+10];
int mmax[MAXN+10];
int a[MAXN+10];
int main()
{
    int n,m;
    int i,j,mmmax;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            mmax[i]=0;
            dp[i]=0;
        }
        dp[0]=0;
        mmax[0]=0;    
        for(i=1;i<=m;i++)
        {
                mmmax=-INF;
                for(j=i;j<=n;j++)
                {
                    dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]);
                    mmax[j-1]=mmmax;
                    mmmax=max(mmmax,dp[j]);
                }    
        }  
        printf("%d
",mmmax);  
          
    } 
    return 0;   
}    
View Code

要么优秀要么生锈
原文地址:https://www.cnblogs.com/Superwalker/p/7853597.html