【基础DP】hdu 1024

题目链接

题目描述

给n个数,把n个数划为m段求划为m段的最大值,并不需要把所有数都划进去。

思路

因为是求将n个数划为m段的最大数,所以建立的状态 dp[i][j] 表示前 j 个数种划 i 段的最大值。
状态转移方程就有两种:
dp[i][j-1] + a[j] 表示把第 j 个数合并到前一段中
dp[i-1][j-1] + a[j] 表示让第 j 个数独立成段
因为题目给的空间比较小,所以需要状态压缩一下
f[j-1] 就表示 dp[i-1][j-1] ,也就是前 j-1 个数中 i-1 段的最大值

代码

#include
using namespace std;

const int inf=0x3f3f3f3f;
const int N=1e6+10;
int a[N];
int dp[N];
int f[N];

void solve(int m, int n)
{
    for(int i=1; i<=n; i++) {
        scanf("%d",&a[i]);
        dp[i]=f[i]=0;
    }
    int mx;
    for(int i=1; i<=m; i++) {
        mx=-inf;
        for(int j=i; j<=n; j++) {
            dp[j]=max(dp[j-1],f[j-1])+a[j];
            f[j-1]=mx;		//每次更新f[j-1],为下一次i的增加使用做准备
            mx=max(mx,dp[j]);
        }
    }
    printf("%d\n",mx);
}

int main()
{
    //freopen("in.txt","r",stdin);
    int m,n;
    while(~scanf("%d %d",&m,&n)) {
        solve(m,n);
    }
    return 0;
}

你可能感兴趣的:(DP)