• luogu P1776 宝物筛选_NOI导刊2010提高(02) | 多重背包(二进制拆分)


    有许多种物品,每种物品有多个,个数已知,求最大价值

    luogu P1776 宝物筛选_NOI导刊2010提高(02)

    假设物品 a 有 34 个

    那么将34拆分为1,2,4,8,16,3总共6个数

    这6个数可以任意组合表示从1到34所有的数

    那么就将1个a物品,2个a物品,4个a物品......各自看成一个整体,它们各自的取与不取可以表示从取1 个a物品到取34个a物品的所有可能

    拆分之后即为01背包问题

    #include<cstdio>
    using namespace std;
    int n,maxw,v[100010],w[100010],m[100010],vi,wi,mi,x,ans[100010];
    int main()
    {
        scanf("%d%d",&n,&maxw);
        int k=0;
        for(int i=1;i<=n;i++)
        {
            x=1;
            scanf("%d%d%d",&vi,&wi,&mi);
            while(x<=mi)
            {
                mi-=x;
                k++;
                v[k]=vi*x;
                w[k]=wi*x;
                m[k]=mi*x;
                x*=2;
                //printf("k=%d,v=%d,w=%d,m=%d
    ",k,v[k],w[k],m[k]);
            }
            if(mi)
            {
            k++;
            v[k]=vi*mi;
            w[k]=wi*mi;
            m[k]=mi*mi;
            //printf("k=%d,v=%d,w=%d,m=%d
    ",k,v[k],w[k],m[k]);
            }
        }
        for(int i=1;i<=k;i++)
        {
            for(int j=maxw;j>=w[i];j--)
            {
                if(ans[j]<ans[j-w[i]]+v[i]) ans[j]=ans[j-w[i]]+v[i];
            }
        }
        printf("%d",ans[maxw]);
        return 0;
    }
  • 相关阅读:
    奔跑的绵羊js
    13.差分
    12.子矩阵的和
    11.前缀和
    10.高精度除法
    9.高精度乘法
    8.高精度减法
    7.高精度加法
    6.数的三次方根
    5.数的范围
  • 原文地址:https://www.cnblogs.com/QAQq/p/10300939.html
Copyright © 2020-2023  润新知