zoukankan      html  css  js  c++  java
  • [HAOI2008]硬币购物

    Description

    BZOJ1042

    Solution

    一开始以为是4种物品的多重背包计数,感觉好难写啊,就看题解去了。

    结果是容斥??

    其实不是很难,不考虑个数限制的话就是一个完全背包计数,先预处理出来(f[i])表示(i)元花费的完全背包计数。然后每次去掉不合法的,就是(f[s-c[i]*(d[i]+1)]),因为如果不合法,某个东西至少拿(d[i]+1)个。容斥一下就好了。

    Code

    const int N = 100010;
    
    ll c[5], n, d[5], s, f[N];
    
    void main() {
        for (int i = 0; i < 4; ++i) c[i] = read();
        f[0] = 1;
        for (int i = 0; i < 4; ++i)
            for (int j = 0; j < N; ++j)
                if (j >= c[i]) {
                    f[j] += f[j - c[i]];
                }
        n = read();
        while (n--) {
            for (int i = 0; i < 4; ++i) d[i] = read();
            s = read();
            ll ans = 0;
            for (int i = 0; i < 16; ++i) {
                ll cnt = 0, ss = 0;
                for (int j = 0; j < 4; ++j) {
                    if (i >> j & 1) cnt++, ss += c[j] * (d[j] + 1);
                }
                if (ss > s) continue;
                if (cnt & 1)
                    ans -= f[s - ss];
                else
                    ans += f[s - ss];
            }
            printf("%lld
    ", ans);
        }
    }
    

    Note

    物品个数很小的计数问题可以考虑容斥。

  • 相关阅读:
    poj 2262
    poj 1050
    poj 1730
    poj 1061
    【设计模式】简单工厂模式学习
    【待学】
    [设计模式]策略模式和单一职责
    Windows live writer 误删 草稿 恢复
    [Linq]Linq To Sql (2)
    MVC 学习日志1(上)
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/bzoj1042.html
Copyright © 2011-2022 走看看