1. 程式人生 > >P1450 [HAOI2008]硬幣購物

P1450 [HAOI2008]硬幣購物

ref math code www scanf lin con 影響 原理

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);
    }
}

P1450 [HAOI2008]硬幣購物