分析:记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 }
时间: 2024-10-22 16:12:40