题目链接:
题意:
给定一个长度为L的木棍,我们可以在上面放小木棍,每根木棍有它自己的价值,木棍不能重叠,放在两端的木棍可以露一半出来,问所能得到的最大的价值。
分析:
首先如果两端的木棍都不能伸出来的话那么就是一个简单的
01
背包问题,但是可以有两个木棍露出来,那么我们设
dp[i][j]
表示用长度为
j
的木棍,有
Code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2010*2;
typedef long long LL;
const LL INF = -1e12;
LL dp[3][maxn];
int a[maxn];
int a1[maxn];
LL b[maxn];
int main() {
int t;
int n,v,cas=1;
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&v);
LL ans=0;
v*=2;
for(int i=0; i<n; i++) {
scanf("%d%lld",&a[i],&b[i]);
a[i]*=2;
ans=max(ans,b[i]);
}
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
for(int j = v;j>=a[i]/2;j--){
dp[1][j]=max(dp[0][j-a[i]/2]+b[i],dp[1][j]);
dp[2][j]=max(dp[1][j-a[i]/2]+b[i],dp[2][j]);
if(j>=a[i]){
dp[1][j]=max(dp[1][j-a[i]]+b[i],dp[1][j]);
dp[2][j]=max(dp[2][j-a[i]]+b[i],dp[2][j]);
dp[0][j]=max(dp[0][j-a[i]]+b[i],dp[0][j]);
}
}
}
ans = max(ans,dp[2][v]);
printf("Case #%d: %lld\n",cas++,ans);
}
return 0;
}