主题思想: 动态规划
dp[i][j] 表示前i个段,由前j个数组成。
那么对于第j个数,可以入选,前i段,也可以不入选
如果j组成了第i段,那么j-len[i] 组成i-1 段
dp[i][j]=max(dp[i][j-1],dp[i-1][j-len[i]]+sum[j]-sum[j-len[i]]
AC 代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1005;
int dp[25][maxn]; // dp[i][j] stands for the 1,...i segment ends with j
int n,m;
int a[maxn];
int b[25];
int sum[maxn];
int main()
{
while(scanf("%d",&n)!=EOF){
if(n==0) break;
scanf("%d",&m);
for(int i=1;i<=m;i++)scanf("%d",&b[i]);
sum[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=m;i++){
for(int j=b[i];j<=n;j++){
dp[i][j]=max(dp[i][j-1],dp[i-1][j-b[i]]+sum[j]-sum[j-b[i]]);
}
}
printf("%d\n",dp[m][n]);
}
return 0;
}