zoukankan      html  css  js  c++  java
  • hihocoder1364 奖券兑换

    题目链接

    思路

    乍一看这是一个01背包的裸题。但是数据范围(10^5)是无法承受的。
    但是发现(p_i)(w_i)只有10,也就是说最多只有100种物品。所以可以对他们进行分组。然后用二进制优化多重背包来做。

    二进制优化多重背包

    多重背包是指限定物品数量的一种背包问题。
    多重背包可以转化为01背包来解。也就是枚举当前这种物品选多少个。但是这种做法的复杂度是(O(NVS))S是背包内物品数量。
    然后考虑优化上面的方法。因为每个数字都是可以用二进制来拼凑出来的。所以可以把每个物品的数量拆分成(2^x)这样就能拆分除(log)个物品。每个物品的价值都是(2^x imes w[i])的形式。体积都是(2^x imes p[i])的形式。
    比如一种物品价值为3,体积为2,数量为13。那么这个物品可以拆分成以下物品:

    [w:3 imes 1 p:2 imes 1 \ w:3 imes 2 p:2 imes 2 \ w:3 imes 4 p:2 imes 4 \ w:3 imes 6 p:2 imes 6 ]

    注意最后一个6并不是(2^x)

    代码

    /*
    * @Author: wxyww
    * @Date:   2019-01-20 09:01:19
    * @Last Modified time: 2019-01-20 09:07:51
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    const int N = 100000 + 100;
    ll read() {
       ll x=0,f=1;char c=getchar();
       while(c<'0'||c>'9') {
          if(c=='-') f=-1;
          c=getchar();
       }
       while(c>='0'&&c<='9') {
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }
    int f[N],w[110],p[110],num[110],a[15][15];
    int W,n,tot;
    int main() {
       n = read(),W = read();
       int mx = 0,my = 0;
       for(int i = 1;i <= n;++i) {
          int x = read(),y = read();
          a[x][y]++;
          mx = max(mx,x);my = max(my,y);
       }
       for(int i = 1;i <= mx;++i) {
          for(int j = 1;j <= my;++j) {
             if(a[i][j]) {
                ++tot;
                w[tot] = j;p[tot] = i;num[tot] = a[i][j];
             }
          }
       }
       for(int i = 1;i <= tot;++i) {
          int k;
          for(k = 1;num[i] - k >= k - 1;k <<= 1) {
             for(int j = W;j >= p[i] * k;--j) {
                f[j] = max(f[j],f[j - p[i] * k] + w[i] * k);
             }
          }
          k = num[i] - k + 1;
          for(int j = W;j >= p[i] * k;--j) {
             f[j] = max(f[j],f[j - p[i] * k] + w[i] * k);
          }
       }
       cout<<f[W];
       return 0;
    }
    
  • 相关阅读:
    [转]实习生需要懂的40大基本规矩
    [转]Linux下pppoe配合Drcom插件上网方法介绍......
    收藏一些图书
    [转]30个自我提升技巧
    [转]关于Gmail打不开的解决办法
    [转]李开复经典语录盘点:人生之路在于每次的选择
    [转]哈佛管理世界中智慧
    胡伟武校友在2011年中国科大本科生毕业典礼暨学位授予仪式上的讲话
    Dynamics4.0和Dynamics2011处理Email的方法
    JS实现简单的ToolTip功能
  • 原文地址:https://www.cnblogs.com/wxyww/p/10313839.html
Copyright © 2011-2022 走看看