关于一些基础的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 ...
随机推荐
- centos6.5-搭建LNMP
安装LNMP 一.安装nginx 1.安装相关组件 yum -y install pcre-devel zlib-devel 2.创建启动用户 useradd -M -s /sbin/nologin ...
- oracle 之 cursor:创建存储过程批量执行DDL语句
说明:使用此过程可任意执行批量DDL语句,调用DDL查询语句时,注意转义字符,使用 ' 转义! 需求:批量删除以CUR_TEST开头的表,且有日志记录. 环境准备:建几张以CUR_TEST开头测试表. ...
- 报错 java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp 原因
sql异常 java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestam ...
- tomcat 服务器的几个重要监听 方法 与 使用
1. 总结一下tomcat 服务器里的三种监听 ServletContextListener HttpSessionListener ServletRequestListener 这是我要做的三个自定 ...
- vue 自动生成菜单
import constant from './const' export function getRouters (files) { let filenames = files.keys() let ...
- Maven Archetype 多 Module 自定义代码脚手架
大部分公司都会有一个通用的模板项目,帮助你快速创建一个项目.通常,这个项目需要集成一些公司内部的中间件.单元测试.标准的代码格式.通用的代码分层等等. 今天,就利用 Maven 的 Archetype ...
- 《剑指offer》面试题09. 用两个栈实现队列
问题描述 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能.(若队列中没有元素,dele ...
- codeblocks中报错:'to_string' was not declared in this scope解决方案
在windows下使用codeblocks(编译器采用MinGW)时,有时会遇到"'to_string' was not declared in this scope"的错误,这里 ...
- 在3G移动通信网络信令流程里获取用户电话号的一种方法(中国电信cdma2000)
首先这些关于电话号的的寻找都是在分组域进行的 然后是首先在rp接口的A11接口寻找,没有看到,于是到pi接口,研究radius协议 发现在协议里也不含有与用户电话号码mdn相关的元素 然后偶遇一篇文档 ...
- gin框架中图形验证码的生成和验证
功能和验证码使用原理 本案例中没有使用redis作为缓存,而是使用的内存存储方法 github链接地址 下载命令 go get github.com/mojocn/base64Captcha 请求处理 ...