将弹出 deque 的个数作为 v (不超过 m ), 弹出的值作为 w , 可以考虑分组背包做法
#include<iostream>
using namespace std;
const int N=110,M=1e5+10;
int dp[M],w[N][N];
int c[N];
int s[N];
int n,m;
dp [i]:弹出个数不超过 i 的最大元素和
w [i] [j]:第 i 组共弹出 j 个数的最大元素和
- 如图,第 i 组从队头弹出数至 l 处,从队尾弹出数至 r 处,则第 i 组的最大元素和为图中紫色部分相加,因此考虑使用前缀和
- 遍历 l 的所有可能,根据 j = c[i] - ( r - ( l - 1 ) ) 推出 r ,再根据前缀和知识得出 w [i] [j]
- 分组背包 for 种数 - for 体积 - for 决策
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){ //遍历组数
//(1)
cin>>c[i];
for(int j=1;j<=c[i];j++){
int x;
cin>>x;
s[j]=s[j-1]+x;
}
//(2)
for(int j=1;j<=c[i];j++)
for(int l=1;l<=j+1;l++){
int r=c[i]+l-1-j;
w[i][j]=max(w[i][j],s[c[i]]-s[r]+s[l-1]);
}
//(3)
for(int j=m;j>=0;j--)
for(int k=0;k<=j&&k<=c[i];k++)
dp[j]=max(dp[j],dp[j-k]+w[i][k]);
}
cout<<dp[m];
}