[BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】
题目链接:BZOJ - 1042
题目分析
首先 Orz Hzwer ,代码题解都是看的他的 blog。
这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案。
为了避免重复的方案被转移,所以我们以硬币种类为第一层循环,这样阶段性的增加硬币。
一定要注意这个第一层循环要是硬币种类,并且初始 f[0] = 1。
f[0] = 1;
for (int i = 1; i <= 4; ++i) {
for (int j = B[i]; j <= MaxS; ++j) {
f[j] += f[j - B[i]];
}
}
之后对于每个询问 (A1, A2, A3, A4, S) ,根据容斥原理,我们要求的答案 Ans 就是 f[S] - (硬币1超限制的方案数) - (硬币2超限制的方案数) - (硬币3超限制的方案数) - (硬币4超限制的方案数) + (硬币1,2超限制的方案数) + (硬币1,3超限制的方案数) + (硬币1,4超限制的方案数) + .... - (硬币1,2,3超限制的方案数) - ... + (硬币1,2,3,4超限制的方案数) 。
怎样求硬币1超限制的方案数呢?我们只要先固定取 (A1+1) 个硬币1,剩余的钱数随便取就可以了,就是 f[S - (A1+1) * V[1]] 。
其余的情况都类似。
容斥的部分使用搜索实现。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring> using namespace std; const int MaxN = 7, MaxS = 100000; int n, S;
int A[MaxN], B[MaxN]; typedef long long LL; LL Ans;
LL f[MaxS + 5]; 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 - (A[x] + 1) * B[x]);
DFS(x + 1, k, Sum);
} int main()
{
for (int i = 1; i <= 4; ++i) scanf("%d", &B[i]);
scanf("%d", &n);
f[0] = 1;
for (int i = 1; i <= 4; ++i) {
for (int j = B[i]; j <= MaxS; ++j) {
f[j] += f[j - B[i]];
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= 4; ++j) scanf("%d", &A[j]);
scanf("%d", &S);
Ans = 0ll;
DFS(1, 0, S);
printf("%lld\n", Ans);
}
return 0;
}
[BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】的更多相关文章
- bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理
题目链接 1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1706 Solved: 985[Submit][ ...
- BZOJ1042:[HAOI2008]硬币购物(DP,容斥)
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- BZOJ 1042: [HAOI2008]硬币购物 容斥+背包
1042: [HAOI2008]硬币购物 Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请 ...
- BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )
先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ---------------------------------------------------------- ...
- Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1747 Solved: 1015[Submit][Stat ...
- BZOJ 1042: [HAOI2008]硬币购物 [容斥原理]
1042: [HAOI2008]硬币购物 题意:4种硬币.面值分别为c1,c2,c3,c4.1000次询问每种硬币di个,凑出\(s\le 10^5\)的方案数 完全背包方案数? 询问太多了 看了题解 ...
- BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)
题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...
- bzoj 1042: [HAOI2008]硬币购物【dp】
设f[i]为凑i元的方案数,这个随便dp一下就行了 然后处理限制,我们考虑用容斥,也就是4个超限-3个超限+2个超限-1个超限,这里用状压枚举一下,然后i硬币超限就当做选了d[i]+1个,在s里减去, ...
- bzoj 1042: [HAOI2008]硬币购物【容斥原理+dp】
当然是容斥啦. 用dp预处理出\( f[i] \),表示在\( i \)价格时不考虑限制的方案数,转移方程是\( f[i]+=f[i-c[j]] \),用状压枚举不满足的状态容斥一下即可. #incl ...
随机推荐
- BZOJ 1878 SDOI 2009 HH项链 树状数组 + 脱机处理
标题效果:一些珠子项链.珠具有不同的颜色.我们问了很多次有多少种不同的颜色有过一段范围. 思考:这个问题让我学会聪明的离线实践.按左端点排序问题.加工出来的位置每种颜色首次出现.每一种颜色的下一次出现 ...
- PHP手机获取6为不反复验证码
//存数字数组 $code = array(); while(count($code) < 6){ //产生随机数1-9 $code[] = rand(1,9); //去除数组中的反复元素 ...
- Cstyle的UEFI导读:第18.0篇 NVRAM的工作原理(上)
虽有句话说的好,实用的东西记在脑子里.没有的记在笔记本上. 可是如今的信息量越来越大,并且随着时间的推移记忆力会越来越不可靠,所以仅仅好把近期工作之余看的一些东西记录下来,避免被迅速忘记.这里 ...
- android 50 进程优先级
程序在磁盘叫程序,程序加载到内存运行起来叫进程,优先级5个级别,内存不足的时候会杀掉低级别进程. Active Process:最上面用户可以操作的. Visible Process:可见进程,部分可 ...
- mybatis0205 一对多查询 复杂
查询所有用户信息,关联查询订单及订单明细信息及商品信息,订单明细信息中关联查询商品信息 1.1sql 主查询表:用户信息 关联查询:订单.订单明细,商品信息 SELECT orders.*, user ...
- Java语言基础(六)
Java语言基础(六) 前一章提到的, BigDecimal, DecimalFormat等具体用法,这里就不在说了,网上有许多 一.下面让我们看一个例子(自由落体运动位移) 说明: (1).公式是 ...
- HTML - 键盘事件
Keyboard 事件 onkeydown: 在用户按下按键时触发. onkeypress: 在用户敲击按钮时触发. onkeyup: 当用户释放按键时触发. 示例 <!DOCTYPE html ...
- Android 控件 之 Menu 菜单
http://www.cnblogs.com/Mrs-cc/archive/2012/07/21/2603042.html 1.OptionsMenu (选项菜单)用法总结 使用方法: 方法一:添 ...
- HTML5+移动APP(2)
原理: html 页面负责内容: ui 负责页面样式: js 负责调用原生app方法. html5: html5这部分负责页面,也就是app中你看到的东西,大概的架构和内容 ui: mui 介绍:和H ...
- ^(bitwise exclusive Or).
一个数,进行异或同一个数两次,将得到原来的数,例如: 6 ^ 4 ^ 4 = 6; 0000-0000-0000-0110 ^ 0000-0000-0000-0100 ---------------- ...