ccpc Pick The Sticks(dp特殊处理)

题目地址

题目大意:给出n根筷子的长度和价值,最多可以装在一个长l的容器中,相邻筷子之间不允许重叠,且两边上的筷子,可以伸一半的长度在容器外,求最大价值量

解题思路:初看一眼就是01背包,没错就是01背包,但是有个特殊的地方需要处理,就是容器2边的筷子,将容器的长度X2,筷子的长度X2,那么相当于每根筷子的价值,可以被放0,1,2次,再加一层循环来枚举放筷子的价值量

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll dp[4020][3];

struct Sticks
{
    int l,v;
}sticks[1010];

int main()
{
    int t,n,m;
    scanf("%d",&t);
    int cas = 1;
    while(t--)
    {
        scanf("%d%d",&n,&m);
        ll maxx = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d",&sticks[i].l,&sticks[i].v);
            maxx = max(maxx,ll(sticks[i].v));
            sticks[i].l *= 2;
        }
        m *= 2;
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; i++)
        {
            for(int j = m; j >= sticks[i].l/2; j--)
            {
                for(int k = 0; k <= 2; k++)///放入一半的筷子的数目
                {
                    if(k >= 1)///已经有放入只装一半的筷子
                        dp[j][k] = max(dp[j][k],dp[j-sticks[i].l/2][k-1]+sticks[i].v);///当前筷子放入一半,或者不放入
                    if(j >= sticks[i].l)///放入整枝筷子
                        dp[j][k] = max(dp[j][k],dp[j-sticks[i].l][k]+sticks[i].v);
                }
            }
        }
        for(int i  = 0; i <= 2; i++)
            maxx = max(maxx,dp[m][i]);
        printf("Case #%d: %lld\n",cas++,maxx);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值