P1450 [HAOI2008]硬币购物

P1450 [HAOI2008]硬币购物


完全背包+容斥

真是秒呀

方案数统计。如果无法直接计算出来,可以尝试使用容斥原理进行拼凑。

你看,这个题中的对答案有影响的元素只有4个。

\(2^n\)次方的容斥完全可以做

我们可以使用所有的方案数,减去一个硬币不合法的方案数,加上两个硬币不合法的方案数,然后如此搞一搞

就可以了。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=101000;
long long f[maxn+1000];
long long D[5],d[5];
int main()
{
    long long tot=0;
    for(int i=0;i<=3;i++)   scanf("%lld",&D[i]);
    scanf("%lld",&tot);
    f[0]=1;
    /*for(int i=1;i<maxn;i++)
        for(int j=1;j<=4;j++)
        {
            if(i-D[j]<0)   continue;
            f[i]+=f[i-D[j]];
        }*/
    for(int i=0;i<=3;i++)
        for(int j=D[i];j<=maxn;j++)
            f[j]+=f[j-D[i]];//不考虑限制
    for(int i=1;i<=tot;i++)
    {
        long long C,S;
        int T;
        for(int j=0;j<=3;j++)   scanf("%lld",&d[j]);
        scanf("%lld",&S);
        int ans=0;
        for(int j=0;j<16;j++)
        {
            C=S;T=0;
            for(int k=0;k<=3;k++)
                if(j&(1<<k))
                {
                    C-=(d[k]+1)*D[k];//计算不合法的数值
                    T^=1;
                }
            if(C<0) continue;
            ans=ans+(T ? -1 : 1)*f[C];//进行容斥
        }
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自www.cnblogs.com/Lance1ot/p/9785509.html