题目大意:共有4种硬币,面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买s的价值的东西。请问每次有多少种付款方法
题解:容斥原理
设f[i]为不考虑数量限制时得到面值i的方案数(完全背包)
由容斥原理,ans=价值为s时的方案数(超过限制)−∑(一种硬币超过限制)+∑(两种硬币超过限制)−∑(三种硬币超过限制)……
当硬币x超过限制时,至少使用了d[x]+1个x,于是总费用减去(d[x]+1)∗c[x]
一共只有24种情况,可以用dfs或者二进制枚举
我的收获:不太会容斥啊……
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n,S,T,c[5],d[5];
long long ans,f[100005];
void First()
{
f[0]=1;
for(int i=1;i<=4;i++)
for(int j=c[i];j<=100000;j++)
f[j]+=f[j-c[i]];
}
void Dfs(int x,int k,int sum)
{
if(sum<0) return;
if(x==5){
if(k&1) ans-=f[sum];
else ans+=f[sum];
return;
}
Dfs(x+1,k+1,sum-(d[x]+1)*c[x]);
Dfs(x+1,k,sum);
}
void work()
{
First();
while(T--){
for(int i=1;i<=4;i++) scanf("%d",&d[i]);
scanf("%d",&S);
ans=0;Dfs(1,0,S);
printf("%lld\n",ans);
}
}
void init()
{
for(int i=1;i<=4;i++) scanf("%d",&c[i]);
cin>>T;
}
int main()
{
init();
work();
return 0;
}
本文介绍了一个具体的硬币支付问题,并通过容斥原理求解该问题的方法。问题涉及四种不同面值的硬币,在给定购买次数和商品价值的情况下,探讨了如何计算可能的支付方式数量。
498

被折叠的 条评论
为什么被折叠?



