bzoj1042硬币购物——递推+容斥
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1042
递推,再用容斥原理减掉多余的,加上多减的……(dfs)即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; ll c[5],tot,d[5],s,f[100005]; void dfs(ll x,ll y,ll z)//第x种硬币,选了y个,体积z { if(x>4) { if(y&1)f[s]-=f[z]; else if(y)f[s]+=f[z]; return; } dfs(x+1,y,z); if(c[x]*(d[x]+1)<=z) dfs(x+1,y+1,z-c[x]*(d[x]+1)); } int main() { scanf("%lld%lld%lld%lld%lld",&c[1],&c[2],&c[3],&c[4],&tot); while(tot--) { memset(f,0,sizeof f); scanf("%lld%lld%lld%lld%lld",&d[1],&d[2],&d[3],&d[4],&s); f[0]=1; for(ll i=1;i<=4;i++) for(ll j=c[i];j<=s;j++)//从c[i]开始! f[j]+=f[j-c[i]]; dfs(1,0,s); printf("%lld\n",f[s]); } return 0; }