bzoj1042: [HAOI2008]硬币购物(Dp+容斥原理)

来源:互联网 发布:网络专升本有学位证吗 编辑:程序博客网 时间:2024/05/16 10:54

题目传送门
好强啊我根本没有往容斥原理那方面想。

解法:
先预处理出没有张数限制的方案数。
这样每一个问的答案就是:
所以方案数-第一种硬币超过限制的方案数-第二种硬币超过限制的方案数-第三种硬币超过限制的方案数-第四种硬币的方案数。
然后因为第一种硬币超过限制的方案数包含一部分第二种硬币超过限制的方案数,所以要加会一,二种硬币超过限制的方案数。
其他的同理这就是容斥原理了。。

代码实现:

#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<cmath>#include<queue>using namespace std;typedef long long ll;ll f[110000];ll c[5],d[5],s;ll ans;void dfs(int x,int k,ll sum) {    if(sum<0)        return ;    if(x==5) {        if(k%2==1)            ans-=f[sum];        else            ans+=f[sum];        return ;    }    dfs(x+1,k+1,sum-c[x]*(d[x]+1));    dfs(x+1,k,sum);}int main() {    for(int i=1;i<=4;i++)        scanf("%lld",&c[i]);    memset(f,0,sizeof(f));    f[0]=1;int T;scanf("%d",&T);    for(int i=1;i<=4;i++)         for(int j=c[i];j<=100000;j++)            f[j]+=f[j-c[i]];   //超过限制的方案数    while(T--) {        for(int i=1;i<=4;i++)            scanf("%lld",&d[i]);        scanf("%lld",&s);        ans=0;dfs(1,0,s);        printf("%lld\n",ans);    }    return 0;}
阅读全文
0 0
原创粉丝点击