HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

2022-09-30 21:08阅读: 23评论: 0推荐: 0

Max Sum Plus Plus HDU - 1024 (DP+滚动数组优化)

题意:
n个点,求出m对不相交连续子序列的最大和。

思路:

状态:dp[i][j] 表示前j个数组组成了i个不相交区间的最大和。
转移:
第j个数只有两个状态:

  • 和别的数组成了一个区间
    那么dp[i][j]=dp[i][j1]+num[j]

  • 自己独立成了一个区间
    那么dp[i][j]=dp[i1][k]+num[j]
    其中的dp[i1][k]=max(dp[i1][i2],dp[i1][i1]dp[i1][j1])

综上
dp[i][j]=max(dp[i][j1],dp[i1][k])+num[j]

其中dp[i-1][k]可以用一个变量纪录下来,纪录所求的每个dp[i-1][k]的最大值
优化:
因为每个dp只和上一个有关,所以就可以化成滚动数组求解了

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
const int N = 1e6+ 10;
#define int long long
int n,m;
int a[N];
int dp[2][N];//分成i个块,在前j个选。
int premax[N];
signed main()
{
while(~scanf("%lld %lld",&n,&m)){
for(int i=1;i<=m;i++){
scanf("%lld",&a[i]);
}
memset(dp,0,sizeof dp);
memset(premax,0,sizeof premax);
int maxn=-1e9;
for(int i=1;i<=n;i++){
maxn=-1e9;
for(int j=i;j<=m;j++){
//此时premax是上一层的最大值
dp[i&1][j]=max(dp[i&1][j-1]+a[j],premax[j-1]+a[j]);
//更新为本层的premax
premax[j-1]=maxn;
//更新本层前j的dp最大值
maxn=max(maxn,dp[i&1][j]);
}
}
printf("%lld\n",maxn);//因为最优解一定是分为n块,所以最后一层的maxn就是答案。
}
return 0;
}

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/16746262.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(23)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起