题意:找出k段不相交的子序列,使得和达到最大
题解:参考了传送门
这道题使用dp,设w[i][k]为在k个元素下选定了i段,并且一定选了k这个元素的最大值,设b[i][k]为在k个元素下选定了i段,并且不一定选了k这个元素,最后看下dp状态转移方程:
w[i][k]=max(b[i-1][k-1],w[i][k-1])+a[k]
b[i][k]=max(b[i][k-1],w[i][k])
然后知道了b[i-1][k-1]->w[i][k]->b[i][k],两次的转变中b只是利用两维,w数组每次都会更新, 与上次没什么关联,直接滚动数组即可。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+50;
int sum[maxn];
int dp[2][maxn],w[maxn];
int m,n;
int main()
{
while(scanf("%d%d",&m,&n)!=EOF){
sum[0]=0;
int k;
for(int i=1;i<=n;i++){
scanf("%d",&k);
sum[i]=sum[i-1]+k;
dp[0][i]=0;
}
int t=1;
for(int i=1;i<=m;i++){
for(int k=i;k<=n;k++){
if(k==i){
dp[t][k]=w[k]=sum[k];
}else{
w[k]=max(dp[1-t][k-1],w[k-1])+sum[k]-sum[k-1];
dp[t][k]=max(dp[t][k-1],w[k]);
}
}
t=1-t;
}
printf("%d\n",dp[m%2][n]);
}
return 0;
}