• []HAOI2008] 硬币购物 解题报告 ( 完全背包+容斥原理)


    题目链接:https://www.luogu.org/problemnew/show/P1450

    题目描述:

    题解:

    如果去掉限制的话,这就是一个完全背包。

    我们可以考虑先去掉限制,把这个完全背包做出来。

    这个时候我们先考虑一种硬币超出了限制,其他硬币任意的情况。怎么处理成这种情况呢?我们假设当前超过的硬币是i,我们强制用di+1枚硬币,那么剩下的就是一个

    完全背包了,这个完全背包的值就是我们现在算的第i种硬币超了,其他任意的方案数。

    然后我们考虑容斥,第一种第二种都超额、第一种第三种都超额、第一种第四种都超额、第二种第三种都超额、第二种第四种都超额、第三种第四种都超额的方案在上一步中都被减了两次,所以额外都加一次回来,容斥下去就行了

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    
    int tot;
    int c[5],d[5];
    ll f[100050];
    int main()
    {
        for (int i=1;i<=4;i++) scanf("%d",c+i);
        scanf("%d",&tot);
        f[0]=1;
        for (int i=1;i<=4;i++)
            for (int j=c[i];j<=100050;j++) f[j]+=f[j-c[i]];
        while (tot--)
        {
            for (int i=1;i<=4;i++)
            scanf("%d",d+i);
            int s;
            scanf("%d",&s);
            ll res=0;
            for (int i=0;i<15;i++)
            {
                ll t=s;
                int cnt=0;
                for (int j=1;j<=4;j++) if ((i>>(j-1))&1) {t-=c[j]*(d[j]+1);cnt^=1;}
                if (t<0) continue;
                if (!cnt) res+=f[t];else res-=f[t];
            }
            printf("%lld
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    ZSSR
    分享mysql db 分区分表的shell
    oracle12c的CDB与PDB
    nodejs连接redis
    webservice 访问 网络共享文件夹 权限问题的解决方案
    闭包后感
    简单记录几个wpf学习上的问题[ObservableQueue]
    源码分析之Iterable&Collection(一)
    数据结构之树(三)
    数据结构之哈希表(二)
  • 原文地址:https://www.cnblogs.com/xxzh/p/9548878.html
Copyright © 2020-2023  润新知