Description
硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买s
i的价值的东西。请问每次有多少种付款方法。
Input
第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000
Output
每次的方法数
Sample Input
1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900
Sample Output
4
27
对于这道题,首先如果没有的限制,那么只要用一个类似于背包的DP就可以在O(s)的时间复杂度下求出答案,设这样求出的总和为s的方案数为,那么运用容斥原理可以得到,下面是程序:
#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long ll;
const int N=100005;
ll f[N]={1};
int c[4],d[4];
void dfs(int x,int k,int now,ll &ans){
if(now<0){
return;
}
if(x==4){
ans+=k&1?-f[now]:f[now];
return;
}
dfs(x+1,k+1,now-c[x]*(d[x]+1),ans);
dfs(x+1,k,now,ans);
}
int main(){
int i,j,t,s;
ll ans;
for(i=0;i<4;i++){
scanf("%d",&c[i]);
}
scanf("%d",&t);
for(i=0;i<4;i++){
for(j=c[i];j<=100000;j++){
f[j]+=f[j-c[i]];
}
}
while(t--){
for(i=0;i<4;++i){
scanf("%d",&d[i]);
}
scanf("%d",&s);
ans=0;
dfs(0,0,s,ans);
printf("%lld\n",ans);
}
return 0;
}