[BZOJ]1042 硬币购物(HAOI2008)
失踪OJ回归。
小C通过这道题mark一下容斥一类的问题。
Description
硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买s的价值的东西。请问每次有多少种付款方法。
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。
Solution
O(s*tot)的DP算法谁都会写,但是看着这时间复杂度你难道不虚吗?
你难道甘愿被卡常而就此丢掉10分或是在刷题时打一个这样的暴力草草了事而对其中的精妙不闻不问,你的良心不会痛吗?
如果你在解题时看到题目中有常数a(a<20)这样的数据,不妨就往O(2a)这样复杂度的算法去想一想。
因为题目中有一个常数4,而且还都是限制条件,所以我们就往状压、容斥这方面去想。
显然状压是不可能的,于是我们就只有容斥了。
首先我们要知道容斥在这道题是干嘛用的:
容斥就是对多个限制条件下方案的去重工作,也就是你们所熟知的,求多个集合的并集。
容斥常常伴随的思想是一种逆向思维,就是题目往往要求我们去求多个集合的交,然而我们并没有好的办法,转而跑去求各个集合的补的并,再补回来就是各个集合的交。
我们需要理解在这个算法中, 交 是可以O(1)求得的,然而 并 需要用容斥求得。
所以解这样的题目的大致思路就是:
题目要求我们求A1~An的交,但是我们发现很难求;
所以我们去求CuA1~CuAn的并,而CuA1~CuAn的并需要我们求CuA1~CuAn的交,但是我们发现CuA1~CuAn的交特别好求,所以我们就圆满地解决了这个问题。
运用这样的思路,我们就可以很快解出这道题。
所以我们要求的只剩,在这次购物中,第 i 种硬币用了超过di的方案数。
脑补一下,我们就知道,我们只要每种硬币先取到它们限制的数量+1,剩下随便取就可以了,这样的方案无论如何都是满足每种硬币都超过限制的。
所以用一句话概括题解:容斥,求f[s-Σ(ci*(di+1))],f[x]为在没有任何限制下,取硬币得到面值x的方案数。
时间复杂度O(max(s)*4+tot*16)。注意答案最大为C(s,4)会爆int。
#include <cstdio> #include <cstring> #include <algorithm> #define ll long long #define MM 100005 using namespace std; int n,m; int a[5],g[5],ys[5]; ll f[MM],lt,ans; bool u;inline int read() {int n=0,f=1; char c=getchar();while (c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}while (c>='0' && c<='9') {n=n*10+c-'0'; c=getchar();}return n*f; }int main() {register int i,j;a[1]=read(); a[2]=read(); a[3]=read(); a[4]=read(); n=read();f[0]=ys[1]=1; ys[2]=2; ys[3]=4; ys[4]=8;for (i=1;i<=4;++i)for (j=a[i];j<MM;++j) f[j]+=f[j-a[i]];while (n--){g[1]=read(); g[2]=read(); g[3]=read(); g[4]=read(); m=read();ans=0;for (i=0;i<16;++i){for (u=lt=0,j=1;j<=4;++j)if (i&ys[j]) u^=1,lt+=1LL*a[j]*(g[j]+1);if (lt>m) continue;ans+=(f[m-lt])*(u?-1:1);}printf("%lld\n",ans);} }
Last Word
大概就是小C关于容斥的一点点想法,当然这样的题目还有很多无法以偏概全。希望这样的思路能对以后有一点帮助吧。
转载于:https://www.cnblogs.com/ACMLCZH/p/7596335.html
[BZOJ]1042 硬币购物(HAOI2008)相关推荐
- BZOJ 1042 [HAOI2008]硬币购物
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1446 Solved: 845 [Submit][Sta ...
- BZOJ 1042: [HAOI2008]硬币购物 [容斥原理]
1042: [HAOI2008]硬币购物 题意:4种硬币.面值分别为c1,c2,c3,c4.1000次询问每种硬币di个,凑出\(s\le 10^5\)的方案数 完全背包方案数? 询问太多了 看了题解 ...
- bzoj 1042: [HAOI2008]硬币购物(dp+容斥)
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2555 Solved: 1537 [Submit][St ...
- 1042: [HAOI2008]硬币购物 - BZOJ
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- [HAOI2008][BZOJ1042] 硬币购物
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1380 Solved: 814 [Submit][Sta ...
- P1450 [HAOI2008]硬币购物
P1450 [HAOI2008]硬币购物 题意: 共有 4 种硬币.面值分别为c1,c2,c3,c4c_1,c_2,c_3,c_4c1,c2,c3,c4. 某人去商店买东西,去了 n 次,对于 ...
- BZOJ1042 [HAOI2008]硬币购物
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买s i的价值的东西.请问每次有多少种付款方法. Input 第 ...
- 【BZOJ1042】硬币购物(动态规划,容斥原理)
[BZOJ1042]硬币购物(动态规划,容斥原理) 题面 BZOJ Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬 ...
- 数论五之容斥——硬币购物,Gerald and Giant Chess,幸运数字,Sky Full of Stars,已经没有什么好害怕的了
容斥的神 [HAOI2008]硬币购物 problem solution code CF559C Gerald and Giant Chess problem solution code [SCOI2 ...
- 【codevs1869】硬币购物,背包+神奇的容斥原理
硬币购物 2008年 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题解 题目描述 Description 一共有4种硬币.面值分别为c1,c2,c3,c4.某 ...
最新文章
- 马斯克要往火星轨道送跑车,在深空待10亿年,静候外星人
- ubuntu mysql 内存满了_ubuntu – 如何为mySQL分配内存限制?
- 架构师之路 — 数据库设计 — 关系型数据库的迁移与版本控制
- AngularJS - 自定义指令
- 华为海思HISILICON
- eclipse里source的快捷方法_Eclipse开发必备快捷键
- python实现指纹识别毕业论文_指纹识别系统大学本科毕业论文
- ruby hash添加数据_如何在Ruby中向Hash添加元素?
- 【script】python字符串相似度匹配
- 利用iptabls的NFLOG记录自己的HTTP HTTPS上网行为
- python计算机入门_Python零基础入门(1)-------计算机基础
- 虚拟机单一网卡设置两个IP
- Java Web编程实战1~3章笔记
- 一百多个实用ZBrush笔刷和Alpah,笔刷使用方法,让建模更简单!
- 拉格朗日插值法总结模板(1~n)
- 考研英语近义词与反义词·十三
- 喜迎B+轮融资,ThingJS母公司优锘科技成为新基建的一匹黑马
- html5体感游戏开发,使用HTML5开发Kinect体感游戏
- Matlab数学建模学习报告(一)
- EAX AX等寄存器之间的关系