zoukankan      html  css  js  c++  java
  • []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;
    }
  • 相关阅读:
    JS单例对象与构造函数对象的区别
    SVG系列
    Js极客之路
    Js极客之路
    iOS微信登录
    iOS HSV
    cocoa pods
    php中请求数据中文乱码
    付费中数字计算
    时间戳对应关系
  • 原文地址:https://www.cnblogs.com/xxzh/p/9548878.html
Copyright © 2011-2022 走看看