zoukankan      html  css  js  c++  java
  • bitset优化背包

    题目:https://agc020.contest.atcoder.jp/tasks/agc020_c

    回忆下一题,是零一背包,主要的做法就是凑出最接近sum/2的价值,然后发现现在的背包的容量是2000*2000,物品数量是2000,那么如果你用正常的

    数组背包的做法的话,8*10^9的复杂度是会超时的,代码如下:

    int n;
        scanf("%d",&n);
        ll sum = 0;
        rep(i,0,n) scanf("%lld",&a[i]),sum+=a[i];
        dp[0] = 1;
        rep(i,0,n) repd(j,(sum+1)/2,a[i]) dp[j] = max(dp[j],dp[j-a[i]]);
        repd(i,sum/2,0) if(dp[i]) return printf("%lld",sum-i),0;
        return 0;

    我们会发现,每个背包的状态要么是零,要么是1,那么我们就可以用bitset来实现速度上的优化:

    8*10^9/64,那么这样的话,是符合时间限制的,代码如下:

    bitset<maxn> bt;
    int main()
    {
        int n,a,sum = 0;
        scanf("%d",&n);
        bt[0] = 1;
        rep(i,0,n){
            scanf("%d",&a);
            bt |= bt<<a;
            sum += a;
        }
        rep(j,(sum+1)/2,sum+1) if(bt[j]) return printf("%d",j),0;
        return 0;
    }

     那么为什么可以用位运算的|(或)呢,因为你看正常的数组做法,

    dp[j] = max(dp[j],dp[j-a[i]]);

    dpj是从dpj-ai转移过来的,所以减去ai就可以相当于位运算的左移

  • 相关阅读:
    python Exception中的raise、assert
    python循环语句与其他编程语言不同之处
    【转】最大似然估计
    尝试发表代码
    奇异分解(SVD)
    Python学习笔记3-string
    梯度下降法
    前后端分离
    Trie树
    HashMap的工作原理以及代码实现,为什么要转换成红黑树?
  • 原文地址:https://www.cnblogs.com/chinacwj/p/8371578.html
Copyright © 2011-2022 走看看