zoukankan      html  css  js  c++  java
  • luogu P1776 宝物筛选_NOI导刊2010提高(02)

    一道多重背包问题

    多重背包就是

    有n种物品,每种物品有各自的价值和体积,并每种物品有一定数目

    给你一个体积v的背包,求最大价值

    我们可以想到把多重背包分解成01背包来做

    复杂度仍然很高

    那我们想到了某种优化(谁想到的???反正不是我

    每个数都可以用二进制来表示,则每个数都可以拆成2的次方的和

    如 18 = 1 + 2 + 4 + 8 + 3(2 + 1)

    而这几个拆出来的数可以组合成18以内的任何数(不信试试鸭

    这样我们可以把多重背包内的每个物品,拆成1,2,4,8……

    一下子就降低了复杂度对吧

    然后来看看题面

    哇多重背包!

    为什么不多进去几次全都拿出来啊好zz

     emmmm

    那我们看代码实现吧

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 10000010//不知道拆成几个所以数组开大一点
    
    int f[maxn],v[maxn],w[maxn];
    int cnt;
    
    int main() {
        int n,W,cnt = 0;
        scanf("%d%d",&n,&W);
        for(int i = 1; i <= n; i++) {
            int value,weight,num;
            scanf("%d%d%d",&value,&weight,&num);
            for(int j = 1; j <= num; j <<= 1) {
                v[++cnt] = j * value;
                w[cnt] = j * weight;
                num -= j;//把物品拆开的操作
            }
            if(num) {
                v[++cnt] = value * num;
                w[cnt] = weight * num;
            }
        }
        for(int i = 1; i <= cnt; i++)
            for(int j = W; j >= w[i]; j--) {
                f[j] = max(f[j],f[j - w[i]] + v[i]);//变成01背包~
            }
        printf("%d",f[W]);
        return 0;
    }

    好啦

    这次不是特别水吧www

  • 相关阅读:
    11.06第十次作业
    (构造方法私有化、this)10.29练习题
    10.23创造人
    10.16(RuPeng)游戏
    10.09
    作业9.25
    练习题
    (随机数之和)求一整数各位数之和1636050052王智霞
    两点之间的距离1636050052王智霞
    TabLayout 简单使用。
  • 原文地址:https://www.cnblogs.com/sevenyuanluo/p/10295988.html
Copyright © 2011-2022 走看看