UVA 11259 Coin Changing Again
题意:有4种硬币,面值分别为c1,c2,c3,c4,然后给出Q组查询。每组查询给出5个数d1,d2,d3,d4,v,分别表示面值为ci的硬币共有di个,然后要求将其凑成总值为v的方案数。
数据范围大致是c<=1000,Q<=100,d,v<=100000。
如果按照普通分组背包的做法,对每组Q都做一遍DP,那么这个复杂度就会达到10^9的级别,肯定会TLE。我也拿不出太好的办法,觉得这题DP不出来。
其实,这题不完全是DP,我觉得这个题目的核心是容斥原理。对于每组查询,算法的复杂度基本上是O(1)这样的常数级的。
在UVA的论坛里看到了大牛的解释:
假设现在只有两种硬币,我们令N=所有凑出v总值的方案数,N1=第一种面值为c1的硬币取了超过d1次凑出总值v的方案数,N2=第二种面值为c2的硬币取了超过d2次凑出总值v的方案数,N12=第一种面值为c1的硬币取了超过d1次且N第二种面值为c2的硬币取了超过d2次凑出总值v的方案数。那么对于一组查询d1,d2,v,合法的方案数就是N-N1-N2+N12.
为了计算这些N,我们利用c1,c2,c3,c4先做一遍背包容量为100000的无限背包,用dp数组记录方案数。
那么计算N的话,直接算用dp[v]就可以了。
怎么计算N1呢?因为c1硬币取了超过了d1次,那么我们就假设它取了d1+1次,共取走了(d1+1)*c1价值的硬币,那么方案数就是dp[v-(d1+1)*c1]。
同理,N2的方案数就是dp[v-(d2+1)*c2],N12的方案数就是dp[v-(d1+1)*c1-(d2+1)*c2]。然后统计N-N1-N2+N12,就可以得到答案了。
现在问题中的硬币种类边成了4个,还是用一样的原理,这时候答案就是N-N1-N2-N3-N4+N12+N13+N14+N23+N24+N34-N123-N124-N134-N234+N1234,一共16项。
1 #include <cstdio> 2 typedef long long LL; 3 LL dp[100010]; 4 5 int main(){ 6 int c[4],d[4],v,Q,kase; 7 scanf("%d",&kase); 8 while(kase--){ 9 dp[0] = 1; 10 for(int i = 1;i <= 100000;i++) dp[i] = 0; 11 12 for(int i = 0;i < 4;i++) 13 scanf("%d",&c[i]); 14 15 for(int i = 0;i < 4;i++) 16 for(int j = c[i];j <= 100000;j++) 17 dp[j] += dp[j-c[i]]; 18 19 scanf("%d",&Q); 20 21 while(Q--){ 22 LL ans = 0; 23 24 for(int i = 0;i < 4;i++) 25 scanf("%d",&d[i]); 26 27 scanf("%d",&v); 28 29 for(int i = 0;i < 16;i++){ 30 int tmp = v; 31 int flag = 1; 32 for(int j = 0;j < 4;j++){ 33 if(i&(1<<j)){ 34 flag = -flag; 35 tmp -= (d[j]+1) * c[j]; 36 } 37 } 38 if(tmp >= 0) ans += flag * dp[tmp]; 39 } 40 41 printf("%lld\n",ans); 42 } 43 } 44 return 0; 45 }
View Code
转载于:https://www.cnblogs.com/zhexipinnong/p/3420455.html
UVA 11259 Coin Changing Again相关推荐
- uva 674 Coin Change 换钱币【完全背包】
题目链接:https://vjudge.net/contest/59424#problem/A 题目大意: 有5种硬币, 面值分别为1.5.10.25.50,现在给出金额,问可以用多少种方式组成该面值 ...
- 【dp - 多重背包】575: Coin Changing
题目: http://acm.swust.edu.cn/#/problem/575/490 题目描述 设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n]中.现要用这些面值的硬币来找钱.可以使用 ...
- UVA 674 Coin Change ,Commence
记忆化搜索,初期.个人感觉从DFS的角度理解DP状态更好一些 #include <map> #include <set> #include <list> #incl ...
- Coin Changing
题目描述 设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n]中.现要用这些面值的硬币来找钱.可以使用的各种面值的硬币个数存于数组Coins[1:n]中. 对于给定的1≤n≤10,硬币面值数组T ...
- 算法——Coin Changing(最少硬币数)
题目描述 设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n]中.现要用这些面值的硬币来找钱.可以使用的各种面值的硬币个数存于数组Coins[1:n]中. 对于给定的1≤n≤10,硬币面值数组T ...
- UVa在线比赛单题汇总-----DP专题
动态规划基础 例题 LA 3882 UVa 3882 - And Then There Was One 递推------------无力orz UVa 10635 10635 - Prince and ...
- 动态规划总结与题目分类
源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...
- 『ACM-算法-动态规划』初识DP动态规划算法
一.多阶段决策过程的最优化问题 在现实生活中,有类活 动的过程,由于 它的特殊性,可将过程分成若干个互相阶段.在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.当阶段决策的选取不是任意确 ...
- (转)dp动态规划分类详解
dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...
最新文章
- 安装java打开.jar文件
- Java面试题技术类一
- STm32 使用 stm32cube GPIO 点亮 led 的
- 简单实现KeyChain实例
- 狗窝里的小日子- 2 ...
- 高通在物联网领域已经深耕多年
- Https java信任_java访问非经过信任证书https的方法
- 【kafka】google提供的一些好用的并发工具类
- havlenapetr ffmpeg的移植
- Kali Linux渗透测试实战 1.3 渗透测试的一般化流程
- 开源日志系统log4cplus(三)
- [转载] python中字典中追加_python 中字典中的删除,pop 方法与 popitem 方法
- IDEA插件系列(100):CPU Usage Indicator插件——显示CPU使用情况
- 小米路由器4a开发版固件_发现篇免拆刷小米路由器4a千兆版刷第三方固件的贴子!...
- emcc生成wasm,wast,bc文件的方法
- 红警战网服务器端源码,红色警戒2战网平台完整版
- 这3种管理者是“企业毒瘤”,须根除
- 解决fatal error C1060: 编译器的堆空间不足(详解)
- 学习总结《反本能---如何对抗你的习以为常》
- 手游辅助制作原理和学习思路