hdu1024 Max Sum Plus Plus

时间:2023-01-16 20:12:20

动态规划,给定长度为n(≤1e6)的整数数组和整数m,选取m个连续且两两无交集的子区间,求所有方案中使得区间和最大的最大值。

dp[i][j]表示结束位置(最后一个区间最后一个元素的位置)为i且选取区间数为j的最大值。

容易得到以下状态转移方程:

hdu1024 Max Sum Plus Plus
 

又:

 
 
 
hdu1024 Max Sum Plus Plus
 

考虑到数组的规模和j的更新特征,使用一维滚动数组取代二维数组,最外层循环枚举j到m即可。

用dp[0][i]表示dp[i][j], dp[1][i]表示max(dp[k][j-1]) (k≤i)。

复杂度为O(n^2) 。

 #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
typedef __int64 LL; const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + ; int s[maxn];
LL dp[][maxn];
LL ans, maxi;
int n, m; int main(){
while(~scanf("%d%d", &m, &n)){
for(int i = ; i <= n; i++) scanf("%d", &s[i]);
ans = maxi = -inf;
memset(dp, , sizeof dp);
int o = ;
for(int j = ; j <= m; j++){
maxi = -inf;
for(int i = j; i <= n; i++){
dp[][i] = s[i] + max(dp[][i - ], dp[][i - ]);
}
for(int i = j; i <= n; i++) maxi = dp[][i] = max(maxi, dp[][i]);
}
for(int i = m; i <= n; i++) ans = max(ans, dp[][i]);
printf("%I64d\n", ans);
}
return ;
}
 
hdu1024 Max Sum Plus Plus