HDU 题解 1024

来源:互联网 发布:淘宝桔子表行假货 编辑:程序博客网 时间:2024/04/29 10:28

//朴素的想法

//DP[M][I];把前I个数中M组的最大和

//那么状态的转移方程就是;

1:

第I个数不在M组中;

DP[M][I]=DP[M][I-1];

第i个自成一组

DP[M][I]=DP[M-1][K]+A[I](K<I);

然后就是状态转移;

但是直接按照我们上面的那个状态转移方程式的话那个复杂度将会是O(N*M*K)的,承受不起呀;

这个时候新的主意就闪亮登场了。因为

dp[m][i]=max(dp[m][i-1],max(dp[m-1][k])+a[i]);

其中max(dp[m-1][k]其实在我们遍历的过程中我们就已经算出来了;

这样我们的话我们可以用一个数组把他们保存下来,这样的话复杂度就直接变成了O(N*M);

接着这道题还有一个细节问题,那就是他其实没给出N的范围;

这样的话我们可以优化一下空间复杂度,这样就大功告成了;

下面附上代码:

#include<iostream>#include<stdio.h>using namespace std;const int maxn=1000000;#define inf 0x7fffffffint dp[maxn+10];int mmax[maxn+10];//保存中间最大值的数组int a[maxn+10];int main(){    int n,m;    while(scanf("%d%d",&m,&n)!=EOF)    {        int i,j,max1;        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);            dp[i]=0;            mmax[i]=0;        }        dp[0]=0;        mmax[0]=0;        for(j=1;j<=m;j++)        {             max1=-inf;            for(i=j;i<=n;i++)            {                dp[i]=max(dp[i-1]+a[i],mmax[i-1]+a[i]);                mmax[i-1]=max1;//这一步和下一步不要搞混了。不然会错的。特别要注意下顺序。                max1=max(dp[i],max1);            }        }        cout<<max1<<endl;    }}//大功告成


0 0
原创粉丝点击