看题解,抄代码。。
这个地方和之前的还是有共同之处,就是都选定第j个, 然后用东西维护。。 这里是用 mmax来维护,而不是用dp的两个一维数组维护,因为怕会混
#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++)
{//Status[i][j]表示前i个数在选取第i个数的前提下分成j段的最大值,
mmmax=-INF;
for(j=i;j<=n;j++)
{//dp[j]表示包含了第j个
dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]);//first:没有分组,且是一定选了第j-1个,second:分了组,一定没有选第j-1个
mmax[j-1]=mmmax;
mmmax=max(mmmax,dp[j]);//mmax用于维护前j-1个的最大值,因此mmmax可以是不含第j个的
}
}
printf("%d\n",mmmax);
}
return 0;
}
2017年5月4日14:43:06:
又忘了为什么会这样。。
再看的时候
没有用动态转移方程:dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j]) (0<k<j)
自己敲了几下别的转移方程,,都错了。。
跟着敲的代码也是错的。。
其实这个地方滚动数组和用 mmax来维护是很经典的。。
int main(){
while(~sf("%d%d",&m,&n)){
for(int i=1;i<=n;++i)sf("%d",&a[i]);
for(int i=1;i<=m;++i){
int tmp=-INF;
for(int j=i;j<=n;++j){
dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]);
mmax[j-1]=max(tmp,mmax[j-1]);
tmp=max(dp[j-1],tmp);
}
}
cout<<dp[n]<<endl;
}
}
本文介绍了一个使用动态规划解决的问题,并通过实例代码展示了如何利用mmax数组优化算法,避免使用两个一维数组进行维护,从而提高效率。
1233

被折叠的 条评论
为什么被折叠?



