题意。给你一个 长度为L 的背包, [0,2000]
再给你n根长度为ai的木棍,其本身价值为vi;
然后只要木棍的重心放进背包就算放进去。问最多不重叠的放置能拿的价值。
题解: 01背包, 重心放进去, 意思就是两端有两个放一半的就行。中间01背包。
那么开一个 dp[i][[j][k]. 代表使用i根木棍 占用j空间,端点有K个需要折半放。
#include<string>
#include<vector>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#define ll long long
#define x first
#define y second
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int mod=11;
const int maxn=1111;
struct node{
ll w,v;
}a[maxn];
ll dp[4040][3];
int main(){
int t,n,m,ca=1;
ll ans;
cin>>t;
while(t--){
memset(dp,0,sizeof(dp));
cin>>n>>m;
m*=2;ans=0;
for(int i=1;i<=n;++i){
scanf("%lld %lld",&a[i].w,&a[i].v);
a[i].w*=2;
ans=max(a[i].v,ans);
}
for(int i=1;i<=n;++i){
for(int j=m;j>=a[i].w/2;--j){
for(int k=0;k<3;++k){
if(j>=a[i].w) dp[j][k]=max(dp[j][k],dp[j-a[i].w][k]+a[i].v);
if(k>0) dp[j][k]=max(dp[j][k],dp[j-a[i].w/2][k-1]+a[i].v);
ans=max(ans,dp[j][k]);
}
}
}
printf("Case #%d: %lld\n",ca++,ans);
}
return 0;
}