#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const int maxn = 4e3+50;
struct node
{
ll l;//
ll val;//
}o[maxn];
ll dp[maxn][3];// 第一维 代表当前容量 第二维度代表 0块超出 1块超出 2快超出的情况
//ll max(ll x, ll y)
//{
// return x>y? x:y;
//}
int main()
{
int T;
scanf("%d", &T);
int cnt = 0;
while(T--)
{
memset(dp, 0, sizeof(dp));
cnt++;
int n, L;
scanf("%d %d", &n, &L);
ll ans = 0;
for(int i = 1;i <= n;i++)
{
scanf("%lld %lld",&o[i].l, &o[i].val);
ans = max(o[i].val, ans);//处理 一根金条两边都超的情况
o[i].l*=2;// 金条的长度扩展为2 用于处理一边超出, 避免除以2 有小数
}
L*=2;
for(int i = 1;i <= n;i++)//循环金条
{
for(int v = L;v >= o[i].l/2;v--)// 跑容量
{
for(int k = 0;k <= 2;k++)/** 必须从 0 跑到2 先得到小的 才能转移大的**/
{
if(k >= 1)
{
// 一块超出 是在 0块超出的情况下转移过来的 , 两块超出是在 1块超出条件下 转移过来的
dp[v][k] = max(dp[v- o[i].l/2][k-1]+o[i].val , dp[v][k]);
}
else if(v >=o[i].l&& k == 0)
{
dp[v][k] = max(dp[v- o[i].l][k]+o[i].val, dp[v][k]);
}
}
}
}
ans = max(ans, dp[L][0]);
ans = max(ans, dp[L][1]);
ans = max(ans, dp[L][2]);
printf("Case #%d: %lld\n", cnt, ans);
}
return 0;
}
[HDU-5543]——01背包变形体
最新推荐文章于 2019-11-18 19:56:01 发布