[HDU-5543]——01背包变形体

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值