关于一些基础的dp——硬币的那些事(dp的基本引入)
1.最少硬币问题大体题意:
有n种硬币,面值分别是v1,v2......vn,数量无限,输入一个非负整数s,选用硬币使其和为s,要求输出最少的硬币组合。
我们可以这样分析:
定义一个名为Min[s]的数组来表示是金额s所对应的最少硬币的组合,所以对我们来说,只要是在程序中查到Min[i]的大小就可以知道最少的硬币组合是多少了。
以面值为{1,5,10,25,50}为例子来讲一下,方便以后备赛。
假如我们输入的s是100,当全用1coin的时候,如图:(画的很拙劣,抱歉)
那么第一个格子里指的就是当金额为0的时候所需要的硬币数是0,那当金额为1的时候Min[1]=Min[1-1]+1,以此类推,当然,这是只使用硬币面值为1的时候。
当我们加入了面值5,就变成了这样子:
我们可以看到,到了5的时候,选择就变成了两种——一个是5个1元的硬币,另一个是直接一个5元的硬币,可以这么理解:
Min[5]=min(Min[5],Min[5-5]+1),这样才能保证硬币数是最小的。
我们还有其他面值的硬币,当然也要一一的引入。
所以说,我们在dp中将Min[i]这种记录问题最优解的数据叫做“状态”,从Min【i-1】,Min【i-5】这种式子叫做状态转移,在问题中,我们可以清晰的看见动态规划往往是利用问题前面的状态,也就是利用子问题的关联性去解决问题,这是dp的一大特点。
本题题解如下:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int Min[251];//每个金额所对应的最少的硬币数
4 int coin[5]={1,5,10,25,50};//5种金额
5 int Min_path[251]={0};
6 void ans()
7 {
8 for(register int k=0;k<251;k++)
9 Min[k]=INT_MAX;//定义初始值是无穷大
10 Min[0]=0;
11 for(register int j=0;j<5;j++)
12
13 for(register int i=coin[j];i<251;i++)
14 {
15 Min_path[i]=coin[j];
16 Min[i]=min(Min[i],Min[i-coin[j]]+1);
17 }
18 }
19 /*void print_ans(int *coin_path,int s)//打印组合
20 {
21 while(s)
22 {
23 cout<<Min_path[s]<<' ';
24 s=s-Min_path[s];
25 }
26 }*/
27 int main()
28 {
29 ios::sync_with_stdio(false);
30 int s;
31 ans();//打表
32 cin>>s;
33 cout<<Min[s]<<endl;
34 //print_ans(Min_path,s);
35 return 0;
36 }
但是对于所有硬币问题,就不能这么解了。
2.所有硬币问题大体题意如下(HDUOJ2069,但是HDUOJ进不去了):
有n种硬币,面值依旧是前面那些巴拉巴拉,到最后就不一样了,要求输出所有硬币组合。
我们这一局采用dp来解,用dp[i][j]来表示当金额为i的时候最少需要j枚硬币。
dp[0][0]是0,那dp[1][1]就是dp[1-1][1-1]+1,画图表示一下:
那我们可以一次类推dp[i][j]=min(dp[i][j],dp[i-coin[k]][j-1]
可以看到,dp[i][j]纵坐标的结果相加就是最少硬币的组合。
代码如下:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int ans[251];
4 int coin[5]={1,5,10,25,50};
5 int dp[251][101];
6 void solve()
7 {
8 dp[0][0]=1;//0元0个硬币算是一种方案
9 for(int i=0;i<5;i++)
10 {
11 for(int j=1;j<101;j++)//硬币数不超过100
12 {
13 for(int k=coin[i];k<251;k++)
14 {
15 dp[k][j]+=dp[k-coin[i]][j-1];
16 }
17 }
18 }
19 }
20 int main()
21 {
22 int s;
23 solve();
24 cin>>s;
25 for(int i=0;i<251;i++)
26 {
27 for(int j=0;j<101;j++)
28 {
29 ans[i]+=dp[i][j];
30 }
31 }
32 cout<<ans[s]<<endl;
33 }
这就是基础的dp引入,硬币问题就解决了。
sdutoj
有一个最少硬币问题:https://acm.sdut.edu.cn/onlinejudge3/problems/1725?from=%2Fsets%2F17
但这个就不是dp的简单引入了,这个属于多重背包啦~~~
关于一些基础的dp——硬币的那些事(dp的基本引入)的更多相关文章
- [DP]硬币问题
今天再写一下硬币问题 为什么是再呢 这是个很羞耻的话题 昨天写了一遍硬币 在某谷上跑 没错 挂掉了 TLE MD_SB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP
BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 ...
- hdu5800 To My Girlfriend dp 需要比较扎实的dp基础。
To My Girlfriend Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- dp乱写2:论dp在不在dp中(但在dp范畴)内的应用
最近正儿八经的学习了dp,有一些题目非常明显看出来就是dp了比如说:过河卒.方格取数.导弹拦截.加分二叉树.炮兵阵地更加明显的还有:采药.装箱问题.过河.金明的预算方案.今天来谈谈dp的dp在不在dp ...
- Atcoder Educational DP Contest I - Coins (概率DP)
题意:有\(n\)枚硬币,每枚硬币抛完后向上的概率为\(p[i]\),现在求抛完后向上的硬币个数大于向下的概率. 题解:我们用二维的\(dp[i][j]\)来表示状态,\(i\)表示当前抛的是第\(i ...
- [提升性选讲] 树形DP进阶:一类非线性的树形DP问题(例题 BZOJ4403 BZOJ3167)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7337179.html 树形DP是一种在树上进行的DP相对比较难的DP题型.由于状态的定义多种多样,因此解法也五 ...
- 【转】斜率优化DP和四边形不等式优化DP整理
(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...
- POJ2411Mondriaan's Dream(DP+状态压缩 or 插头DP)
问题: Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after prod ...
- <DP> (高频)139 375 374 (DP hard)312
139. Word Break 返回结果较为简单可用dp, 复杂用dfs class Solution { public boolean wordBreak(String s, List<Str ...
随机推荐
- awk流程控制
awk 中if和for while 一.awk嵌套if判断语句 格式如下: if(表达式) {语句1} else if(表达式) {语句2} else {语句3} 如果if后边的语句块是的单个语句,{ ...
- 《python深度学习》(高清、源码).PDF,免费无需任何解压密码
链接:https://pan.baidu.com/s/1zx20XEpPBJeBG2e1IGMc6g 提取码:wub3
- store在模块化后,获取state中的值时undefined
目录结构 用this.$store.getters.showNotif ,加上模块名this.$store.getters.apply.showNotif都取不到值, 控制台打印store,发现这样的 ...
- VMware桥接模式连接局域网和互联网
第一步:确认本地网关地址 第二步选择桥接模式: 我比较幸运,桥接到"自动",就已经连接成功.不用逐个试错. 修改 ifcfg-ens33 和 新建 ifcfg-br0 [root@ ...
- GoLang设计模式19 - 桥接模式
桥接模式是一种结构型设计模式,通过桥接模式可以将抽象部分和它的实现部分分离.这看着有点儿奇怪,接下来会作详细说明. 桥接模式建议将一个较大的类拆分成两中角色. 抽象角色 - 抽象角色是一个接口.它的子 ...
- .Net 线程安全集合
.Net 提供了基于生产-消费模式的集合类,这些集合对多线程访问安全,定义在System.Collections.Concurrent名称空间中.这个名称空间中包括基础接口IProduceConsum ...
- 【原创】美团二面:聊聊你对 Kafka Consumer 的架构设计
在上一篇中我们详细聊了关于 Kafka Producer 内部的底层原理设计思想和细节, 本篇我们主要来聊聊 Kafka Consumer 即消费者的内部底层原理设计思想. 1.Consumer之总体 ...
- CSS设置标签、图片放大、缩小、旋转、移动(tranform)
CSS设置标签.图片放大.缩小.旋转.移动(tranform) 1.缩小和放大属性(scale) 格式:tranform:缩小类型(数值): 注意:缩小和放大都是 scale : 其中的值(0~1)代 ...
- 解决Post请求中文乱码问题
解决Post请求中文乱码问题 req.setChracterEncoding()要在获取请求参数前调用才有效,不然还是乱码
- pyhon笔记入门
人生苦短,我用Python 博客园精华区01-15 23:46 (一)认识Python Python背景介绍 Python的格言: Life is short,use python. (人生苦短,我用 ...