hdu1024Max Sum Plus Plus

之前在书里看过了,但是没有做过例题,忘记它的原理了

dp[i][j]表示前i个数中选j段所能构成的最大值,(强调一下,这j段包括最后一个元素[i]的),这样第i个元素要不跟倒数第二个一起,要不独自形成一段——第j段
dp[i][j]=max(dp[i-1][j], dp[i-len[j]][j-1]+sum) len[j]表示第j段的长度,sum表示长度为len[j]的

当然得用优化算法,这是优化算法是在书里面看到的,挺巧妙的

for(i=1;i<=m;i++){
max=-INF;
for(j=i;j<=n;j++){
dp[j]=maxb(dp[j-1]+num[j],pre[j-1]+num[j]);
pre[j-1]=max;
max=maxb(max,dp[j]);
}

dp指上面的dp[i][j],pre记录第j个数前最大的dp

说说我的看完题解后,自己的敲的代码错在哪里吧

for(i=1;i<=m;i++)把这里的m改成n就错了,因为这里的m是指段数

for(j=i;j<=n;j++)把这里的j=i改成j=1就错了,因为i段的话,至少都要从第i个数开始吧

for(i=0;i<=n;i++){pre[i]=0;dp[i]=0;}把这个换成memset(pre),memset(dp)超时了,毕竟是1000000次吗,浪费太多操作了

贴上我的ACCEPT代码吧

#include "iostream"
#include "string.h"
#define INF 9999999;
using namespace std;
int maxb(int a,int b){return a>b?a:b;}
int pre[1000010],dp[1000010],num[1000010];

int main(){
  int m,n,i,j,max;
  while(cin>>m>>n){
    for(i=1;i<=n;i++)cin>>num[i];
    for(i=0;i<=n;i++){pre[i]=0;dp[i]=0;}
    for(i=1;i<=m;i++){
      max=-INF;
      for(j=i;j<=n;j++){
       dp[j]=maxb(dp[j-1]+num[j],pre[j-1]+num[j]);
       pre[j-1]=max;
       max=maxb(max,dp[j]);
     }
   }
   cout<<max<<endl;
  }
}
原文地址:https://www.cnblogs.com/dowson/p/3277432.html