[HAOI2018]硬币购物

[HAOI2008]硬币购物

https://ac.nowcoder.com/acm/problem/19974

[HAOI2018]硬币购物

都这年头了,还有谁购物用硬币的吗?

题目大意

首先,你有四种面值的硬币

然后你会出门采购

每次出门,你都会带上一些硬币,每种硬币的个数给定

然后你买了的东西

问你有多少种付款的方案

分析

直接写裸的背包的时间复杂度直接炸天

那么正难则反是一个十分优秀的想法

就是说,可以不计代价的用总的方案减去不合法的方案

那么剩下的全是合法的了

那么,就要分别统计

这四种硬币构成的所有集合的不合法的方案

及当且仅当上述集合中的种类的硬币不满足条件是的总方案数

怎么求?

首先,可以用到二进制枚举子集,得到上述个集合

然后考虑容斥

可以得到,子集大小为奇数的容斥系数为,而偶数的容斥系数为

那么这部分可以表示如下:

inline void Solve()
{
        for (int i = 1; i < 16; ++i) {
            int size = tot;
            cke = 0;
            for (int state = i, j(0); state; ++j, state >>= 1)
                if (state & 1) cke ^= 1, size -= s[j] * (d[j] + 1);
            if (size >= 0) {
                if (cke & 1) ans -= f[size];
                else ans += f[size];
            }
        }
}

那么最后用整体减一下就可以了

code

signed main()
{
    for (int i = 0; i < 4; ++i) {
        s[i] = __read();
        for (int j = s[i]; j < maxn; ++j)
            f[j] += f[j - s[i]];
    }
    int T = __read();

    while (T--) {
        for (int i = 0; i < 4; ++i)
            d[i] = __read();

        int tot = __read(), cke(0);
        ll ans(f[tot]);
        Solve();
        printf ("%lld\n", ans);
    }
    system("pause");
}
有的没的 文章被收录于专栏

RT,有的没的

全部评论
硬币还是有的 不然需要抛硬币的时候就不知道咋办了
点赞 回复 分享
发布于 2020-09-24 14:02
Emmm牛客屏蔽有点厉害
点赞 回复 分享
发布于 2020-09-23 23:44
lhj
点赞 回复 分享
发布于 2020-09-23 23:44
打***用)
点赞 回复 分享
发布于 2020-09-23 23:44

相关推荐

mjasjon:这种trash中厂 简历过筛概率比大厂还低(除阿里系)
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
04-14 20:10
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
评论
2
3
分享

创作者周榜

更多
牛客网
牛客企业服务