[HAOI2008]硬币购物

容斥+背包。

先做完全背包,然后就去掉用的硬币大于限量的,用容斥原理去下重就行了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100005;
int c[5],T;long long f[N];int d[5],s;
int main() {
    for(int i=1;i<=4;i++) scanf("%d",&c[i]);
    scanf("%d",&T);
    f[0]=1;
    for(int j=1;j<=4;j++)
    for(int i=c[j];i<=N-5;i++)
    f[i]+=f[i-c[j]];
    while(T--) {
        for(int i=1;i<=4;i++) scanf("%d",&d[i]);
        scanf("%d",&s);
        long long ans=0;
        for(int i=0;i<=15;i++) {
            long long tp=s;short rc=1;
            for(int j=0;j<4;j++) 
                if(i&(1<<j)) tp-=c[j+1]*(d[j+1]+1),rc=-rc;
            if(tp<0) continue;
            ans+=f[tp]*rc;
        }
        printf("%lld
",ans);
    }
    return 0;
}    
[HAOI2008]硬币购物
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9745658.html