[HAOI 2008]硬币购物
Description
硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。
Input
第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000
Output
每次的方法数
Sample Input
3 2 3 1 10
1000 2 2 2 900
Sample Output
27
题解
显然直接用多重背包做会超时,先不考虑每种硬币数量的限制,设$f[i]$为不考虑每种硬币数量的限制时,面值为$i$的方案数,则状态转移方程就呼之欲出了:$f[i]={\sum f[i-c[k]]}$,$i-c[k]>=0$,$1<=k<=4$
为避免方案重复,要以$k$为阶段递推,边界条件为$f[0]=1$,这样预处理的时间复杂度就是$O(s)$。
接下来对于每次询问,根据容斥原理,答案即为得到面值为$S$的不超过限制的方案数=得到面值$S$的无限制的方案数即$f[s]$
– 第$1$种硬币超过限制的方案数 – 第$2$种硬币超过限制的方案数 – 第$3$种硬币超过限制的方案数 – 第$4$种硬币超过限制的方案数
+ 第$1$,$2$种硬币同时超过限制的方案数 + 第$1$,$3$种硬币同时超过限制的方案数 + …… + 第$1$,$2$,$3$,$4$种硬币全部同时超过限制的方案数。
用$dfs$实现,当选择的个数是奇数时用减号否则用加号。
当第$1$种硬币超过限制时,只要要用到$D[1]+1$枚硬币,剩余的硬币可以任意分配,所以方案数为 $F[ S – (D[1]+1)*C[1] ]$,
当且仅当$(S – (D[1]+1)*C[1])>=0$,否则方案数为$0$。其余情况类似,每次询问只用问$16$次,所以询问的时间复杂度为$O(1)$。
//It is made by Awson on 2017.9.24
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const LL N = ;
LL Read() {
char ch = getchar();
LL sum = ;
while (ch < '' || ch > '') ch = getchar();
while (ch >= '' && ch <= '') sum = (sum<<)+(sum<<)+ch-, ch = getchar();
return sum;
}
LL c[], k;
LL f[N+];
LL d[], s;
LL ans; void dfs(int cen, LL cnt, bool mark) {
if (cnt < ) return;
if (cen == ) {
if (mark) ans -= f[cnt];
else ans += f[cnt];
return;
}
dfs(cen+, cnt-c[cen]*(d[cen]+), !mark);
dfs(cen+, cnt, mark);
} void work() {
f[] = ;
for (int i = ; i < ; i++) {
c[i] = Read();
for (int j = c[i]; j <= N; j++)
f[j] += f[j-c[i]];
}
k = Read();
while (k--) {
for (int i = ; i < ; i++)
d[i] = Read();
s = Read();
ans = ;
dfs(, s, );
printf("%lld\n", ans);
}
}
int main() {
work();
return ;
}
[HAOI 2008]硬币购物的更多相关文章
- 【BZOJ-1042】硬币购物 容斥原理 + 完全背包
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1811 Solved: 1057[Submit][Stat ...
- bzoj1042: [HAOI2008]硬币购物
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- 【BZOJ】【1042】【HAOI2008】硬币购物
DP+容斥原理 sigh……就差一点…… 四种硬币的数量限制就是四个条件,满足条件1的方案集合为A,满足条件2的方案集合为B……我们要求的就是同时满足四个条件的方案集合$A\bigcap B\bigc ...
- 1042: [HAOI2008]硬币购物 - BZOJ
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法.Input 第一行 ...
- 【BZOJ1042】【DP + 容斥】[HAOI2008]硬币购物
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1747 Solved: 1015[Submit][Stat ...
- bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理
题目链接 1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1706 Solved: 985[Submit][ ...
- BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )
先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ---------------------------------------------------------- ...
- BZOJ 1042: [HAOI2008]硬币购物 [容斥原理]
1042: [HAOI2008]硬币购物 题意:4种硬币.面值分别为c1,c2,c3,c4.1000次询问每种硬币di个,凑出\(s\le 10^5\)的方案数 完全背包方案数? 询问太多了 看了题解 ...
随机推荐
- 敏捷冲刺每日报告——Day3
1.情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起止时间 2017.10.27 00:00 -- 2017.10.28 00:00 讨论时间地点 2017.10.27晚9:30, ...
- 201621123040《Java程序设计》第六周学习总结
1.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结 2.书面作业 2.1clone方法 2.1.1在te ...
- iOS开发-OC中TabView的编辑
UITableView编辑 1> UITableView 编辑流程 2> UITableView 编辑步骤(四步) ① 第一步 : 让 TableView 处于编辑状态(在按钮点击事件方法 ...
- 从PRISM开始学WPF(六)MVVM(二)Command?
从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...
- git(一)快速入门
1.设置用户名 git config --global user.name '你的用户名' 2.设置用户名邮箱 git config --global user.email '你的邮箱' 3. ...
- jquery 表双击某行时,取出某行中各列的数值.
<script> $(function () { $("tr").dblclick(function () { var txt = $("table tr ...
- CSS揭秘(三)形状
Chapter 3 1. 椭圆 椭圆的实现主要依靠 border-radius 属性,该属性确定边框切圆角的半径大小,可以指定数值 px,也可以使用百分比显示 而且该属性非常灵活,四个角可以分别设置 ...
- Python——cmd调用(os.system阻塞处理)
os.system(返回值为0,1,2) 0:成功 1:失败 2:错误 os.system默认阻塞当前程序执行,在cmd命令前加入start可不阻塞当前程序执行. 例如: import os os.s ...
- Ubuntu16.04建立本地更新源
公司有多台Ubuntu机器,而且不能连接互联网,导致安装软件和更新都比较麻烦,需要建立一台本地更新源服务器. 1.安装apt-mirror工具 sudo apt-get install -y apt- ...
- angular路由守卫
路由守卫是指当用户满足了某些要求之后才可以离开或者进入某个页面或者场景的时候使用.比如说只有当用户填写了用户名和密码之后才可以进入首页,比如说用户离开某个页面时明月保存信息提示用户是否保存信息后再离 ...