首页 > 代码库 > 51nod 1052 最大M子段和(动态规划)

51nod 1052 最大M子段和(动态规划)

技术分享

分析:记dp[x][s][1]为从第x个数开始,剩余s段可以分,1表示x跟上一段连着,0表示不连着,递推式为dp[x][s][1]=max{dp[x+1][s][1]+a[x],dp[x+1][s][0]},dp[x][s][0]=max{dp[x+1][s-1][1]+a[x],dp[x+1][s][0]}.

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn=5005;
 5 typedef long long ll;
 6 ll dp[2][maxn][2];
 7 int n,m,a[maxn];
 8 int main(){
 9     cin>>n>>m;
10     memset(dp,0,sizeof(dp));
11     for(int i=0;i<n;i++)
12         cin>>a[i];
13     for(int i=0;i<=m;i++){
14         dp[0][i][1]=max(0,a[n-1]);
15         if(i==0)continue;
16         dp[0][i][0]=max(0,a[n-1]);
17     }
18     for(int i=0;i<n-1;i++){
19         for(int j=0;j<=m;j++){
20             dp[(i+1)%2][j][1]=max(dp[i%2][j][1]+a[n-2-i],dp[i%2][j][0]);
21             if(j>0)dp[(i+1)%2][j][0]=max(dp[i%2][j-1][1]+a[n-2-i],dp[i%2][j][0]);
22             else dp[(i+1)%2][j][0]=dp[i%2][j][0];
23         }
24     }
25     if(n%2==0)cout<<max(dp[1][m-1][1],dp[1][m][0])<<endl;
26     else cout<<max(dp[0][m-1][1],dp[0][m][0])<<endl;
27     return 0;
28 }

 

51nod 1052 最大M子段和(动态规划)