BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )

本文讨论了使用动态规划解决硬币购物问题的方法,包括如何通过预先计算不同金额的组合数量,以及如何利用容斥原理来计算特定价值商品的付款方案数。通过实例演示了算法实现和输入输出格式。

先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. 

------------------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 100009;
 
ll dp[maxn], ans;
int c[4], d[4], s;
 
void dfs(int x, int w, bool t) {
if(x == 4)
t ? ans -= dp[w] : ans += dp[w];
else {
dfs(x + 1, w, t);
if(w >= ll(c[x]) * (d[x] + 1)) dfs(x + 1, w - c[x] * (d[x] + 1), t ^ 1);
}
}
 
int main() {
for(int i = 0; i < 4; i++) scanf("%d", c + i);
memset(dp, 0, sizeof dp); dp[0] = 1;
for(int i = 0; i < 4; i++)
for(int j = c[i]; j < maxn; j++)
dp[j] += dp[j - c[i]];
int T; scanf("%d", &T);
while(T--) {
for(int i = 0; i < 4; i++) scanf("%d", d + i);
scanf("%d", &s);
ans = 0;
dfs(0, s, 0);
printf("%lld\n", ans);
}
return 0;
}

------------------------------------------------------------------------

1042: [HAOI2008]硬币购物

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 1524   Solved: 892
[ Submit][ Status][ Discuss]

Description

硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

Input

第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s

Output

每次的方法数

Sample Input

1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900

Sample Output

4
27

HINT

数据规模

di,s<=100000

tot<=1000

Source

 

转载于:https://www.cnblogs.com/JSZX11556/p/4872482.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值