Think:
1知识点:基础dp
2题意:n个数分成m部分的最大值
二维表示
dp[i][j]:j个数分成i部分的最大值
状态转移方程
dp[i][j] = max(dp[i][j-1]+a[j], max(dp[i-1][k])+a[j]), 0<k<j
一维优化
dp[j]数组表示前j个数分成当前i部分的最大值
mav[j]数组表示第j层的最大值
状态转移方程
dp[j] = max(dp[j-1]+a[j], mav[j-1]+a[j]);
以下为Accepted代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 4e2;
int dp[N], a[N], mav[N];
/*1.dp[j]数组表示前j个数分成当前i部分的最大值*/
/*2.mav[j]数组表示第j层的最大值*/
int main(){
int m, n, i, j, mx;
while(~scanf("%d %d", &m, &n)){
for(i = 1; i <= n; i++)
scanf("%d", &a[i]);
dp[0] = 0;
memset(mav, 0, sizeof(mav));
for(i = 1; i <= m; i++){
mx = -inf;
for(j = i; j <= n; j++){
dp[j] = max(dp[j-1]+a[j], mav[j-1]+a[j]);
mav[j-1] = mx;
mx = max(mx, dp[j]);/*更新记录分成i部分第j层的最大值*/
}
}
printf("%d\n", mx);/*输出分成m部分的最大值*/
}
return 0;
}