您的位置:首页 > 产品设计 > UI/UE

UESTC 1218 Pick The Sticks (2015 CCPC)

2016-07-31 14:30 169 查看
题目链接

题意就是给你一块长为l的木板,然后有n个木棍,木棍有长度,有价值,可以放在木板上,只要它超出木棍的的长度不超过他自己长度的二分之一,它就可以放上去。

看大家对背包问题的的理解,很明显加一维状态,表示放在边缘没。

下面是代码

细节就是背包边缘的处理

#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#define LL long long
using namespace std;

LL dp[2][8010][3];
LL w[4005],v[4005];

int main()
{
int t,kase = 1;
scanf("%d",&t);
while(t--){
memset(dp,0,sizeof(dp));
int l,n;
scanf("%d%d",&n,&l);
l *= 2;
for(int i=0;i<n;i++){
scanf("%lld%lld",&w[i],&v[i]);
w[i] *= 2;
}
int now = 1 , pre = 0;
for(int i=0;i<n;i++){

for(int j=0;j<=l;j++){
dp[now][j][0] = dp[pre][j][0];
dp[now][j][1] = dp[pre][j][1];
dp[now][j][2] = dp[pre][j][2];
}

for(int j=l;j>=w[i];j--){
dp[now][j][0] = max(dp[pre][j-w[i]][0] + v[i],dp[now][j][0]);
dp[now][j][1] = max(dp[pre][j-w[i]][1] + v[i],dp[now][j][1]);
dp[now][j][2] = max(dp[pre][j-w[i]][2] + v[i],dp[now][j][2]);
}

for(int j=l;j>=w[i]/2;j--){
dp[now][j][1] = max(dp[now][j][1],dp[pre][j-(w[i]/2)][0] + v[i]); // 这里很关键
dp[now][j][2] = max(dp[now][j][2],dp[pre][j-(w[i]/2)][1] + v[i]); // 这里很关键
}
swap(now,pre);
}
LL ans = dp[pre][l][0];
ans = max(ans,dp[pre][l][1]);
ans = max(ans,dp[pre][l][2]);
for(int i=0;i<n;i++) ans = max(ans,v[i]);
printf("Case #%d: ",kase++);
printf("%lld\n",ans);

}
return 0;
}


总之这题算是2015年CCPC的铜牌题。

加油!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: