Codevs3269 混合背包

  • 题目大意:我觉得不用说了,题目已经很明显了。

  • 鉴于01背包和完全背包已经写过了,这次只说多重背包了。利用2进制思想分解,01背包又考虑了某件物品选与不选的情况,这样就成功将问题转化了。

  • 代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,v,f[200005];

int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d",&n,&v);
    while (n--)
    {
        int m,w,flag;
        scanf("%d%d%d",&m,&w,&flag);
        if (flag==1)
        {
            for (int i=v;i>=m;--i)
              f[i]=max(f[i],f[i-m]+w);
        }
        else if (flag==-1)
        {
             for (int i=m;i<=v;++i)
               f[i]=max(f[i],f[i-m]+w);
        }
        else
        {
            if (flag*m>=v)
            {
                for (int i=m;i<=v;++i)
                  f[i]=max(f[i],f[i-m]+w);
            }
            else
            {
                int k=1;
                while (k<flag)
                {
                      for (int i=v;i>=k*m;--i)
                        f[i]=max(f[i],f[i-k*m]+k*w);
                      flag-=k;
                      k*=2;
                }
                for (int i=v;i>=flag*m;--i)
                  f[i]=max(f[i],f[i-flag*m]+flag*w);
            }
        }
    }
    printf("%d",f[v]);
    return 0;
}                                              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值