一、原题地址
二、大致题意
给出一个有n层的架子,可以从中取出m个东西。每层有k个东西,每次可以从最左或者最右取出物品,然后给出的是k个物品的价值。
三、思路
首先处理出每层取j个物品时能获得的最大价值,记作work[i][j]。
然后变成了背包问题。
四、代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf=0x3f3f3f3f;
int n,V;
int sum[300][300],dp[300][10005],maxx[300][300];
int read[300][300];
int main()
{
scanf("%d%d",&n,&V);
for(int i=1;i<=n;i++)
{
int nn;
scanf("%d",&nn);
sum[i][250]=nn;
sum[i][0]=0;
for(int j=1;j<=nn;j++)
{
scanf("%d",&read[i][j]);
if(j==1) sum[i][j]=read[i][j];
else sum[i][j]=sum[i][j-1]+read[i][j];
}
}
memset(maxx,0,sizeof(maxx));
for(int i=1;i<=n;i++)
{
for(int j=0;j<=sum[i][250];j++)
{
for(int l=0;l<=j;l++)
{
int r=j-l,num=sum[i][250];
maxx[i][j]=max(maxx[i][j],(sum[i][num]-sum[i][num-r])+sum[i][l]);
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=V;j>0;j--)
{
for(int k=0;k<=min(j,sum[i][250]);k++)
{
dp[i][j]=max(dp[i][j],dp[i-1][j-k]+maxx[i][k]);
}
}
}
printf("%d\n",dp[n][V]);
getchar();
getchar();
}