• [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

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

  • 相关阅读:
    test1
    servlet的生命周期
    关与JdbcTemplate"的thread "main" org.springframework.jdbc.BadSqlGrammarException
    正则表达式
    @Autowired和@Resource的区别
    kubernetes安装
    docker相关
    KIBANA
    mysql在centos上安装
    MySql不错的文章
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/bzoj1042.html
Copyright © 2020-2023  润新知