zoukankan      html  css  js  c++  java
  • Luogu P1776 宝物筛选_NOI导刊2010提高(02)(多重背包模版)

    传送门

    多重背包板子题,

    多重背包就是每种东西有好几个,可以把它拆分成一个一个的01背包

    优化:二进制拆分(拆成1+2+4+8+16+...)

    比如18=1+2+4+8+3,可以证明18以内的任何数都可以用这几个数的和表示,

    所以就把2个,4个....绑定为一个物品,和一个一个的效果是一样的

    这样就减少了拆分出来的物品的数量。

    代码如下

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int maxn = 200005;
    int n,m,a,b,c,cnt,ans,f[maxn],v[maxn],w[maxn];
    int main() {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++){
            scanf("%d%d%d",&a,&b,&c);
            for(int j = 1;j <= c;j *= 2){
                c -= j;
                v[++cnt] = a*j;
                w[cnt] = b*j;
            }
            if(c){
                v[++cnt] = a*c;
                w[cnt] = b*c;
            }
        }
        for(int i = 1;i <= cnt;i++)
            for(int j = m;j >= w[i];j--){
                f[j] = max(f[j],f[j-w[i]]+v[i]);
                ans = max(f[j],ans);
            }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    CCNP-MPLS-标签交换
    Mac地址表、STP与RSTP原理
    mysql 初始数据库简单操作
    异步回调,事件,线程池与协程
    bug问题
    GIL 线程池
    异常处理
    奇怪的东西
    绑定方法
    初体验
  • 原文地址:https://www.cnblogs.com/mogeko/p/10291916.html
Copyright © 2011-2022 走看看