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的基本引入)的更多相关文章

  1. [DP]硬币问题

    今天再写一下硬币问题 为什么是再呢 这是个很羞耻的话题 昨天写了一遍硬币 在某谷上跑 没错 挂掉了 TLE MD_SB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  2. BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP

    BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 ...

  3. hdu5800 To My Girlfriend dp 需要比较扎实的dp基础。

    To My Girlfriend Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  4. dp乱写2:论dp在不在dp中(但在dp范畴)内的应用

    最近正儿八经的学习了dp,有一些题目非常明显看出来就是dp了比如说:过河卒.方格取数.导弹拦截.加分二叉树.炮兵阵地更加明显的还有:采药.装箱问题.过河.金明的预算方案.今天来谈谈dp的dp在不在dp ...

  5. Atcoder Educational DP Contest I - Coins (概率DP)

    题意:有\(n\)枚硬币,每枚硬币抛完后向上的概率为\(p[i]\),现在求抛完后向上的硬币个数大于向下的概率. 题解:我们用二维的\(dp[i][j]\)来表示状态,\(i\)表示当前抛的是第\(i ...

  6. [提升性选讲] 树形DP进阶:一类非线性的树形DP问题(例题 BZOJ4403 BZOJ3167)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7337179.html 树形DP是一种在树上进行的DP相对比较难的DP题型.由于状态的定义多种多样,因此解法也五 ...

  7. 【转】斜率优化DP和四边形不等式优化DP整理

    (自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...

  8. POJ2411Mondriaan's Dream(DP+状态压缩 or 插头DP)

    问题: Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after prod ...

  9. <DP> (高频)139 375 374 (DP hard)312

    139. Word Break 返回结果较为简单可用dp, 复杂用dfs class Solution { public boolean wordBreak(String s, List<Str ...

随机推荐

  1. 实验 4 :Open vSwitch 实验 —— Mininet 中使用 OVS 命令

    实验 4 :Open vSwitch 实验 -- Mininet 中使用 OVS 命令 一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调 ...

  2. Word2010初识

    原文链接:https://www.toutiao.com/i6487370439910752782/ 认识Word Microsoft Office Word是微软公司的一个文字处理器应用软件. 启动 ...

  3. Allwinner F1C100s coremark测试

    ccu register base:0x01c20000 devmem 0x01c20000 The PLL output=(24MHz*N*K)/(M*P) N=31 K=1 M=1 P=/1 re ...

  4. 使用nginx访问FastDFS fastdfs nginx

    文中所有~~~均为同一个自定义文件夹名字,一般使用项目名称 2.1.为什么需要用Nginx访问? FastDFS通过Tracker服务器,将文件放在Storage服务器存储,但是同组存储服务器之间需要 ...

  5. Redis之持久化方式详解

    背景:Redis之所以能够在技术革新发展迅速的时代超越Memcache等其他Nosql数据库,最主要的一点是Redis提供数据持久化,能够根据持久化策略将缓存数据灵活的写到磁盘上,更好地满足了当下海量 ...

  6. java下拉框转换公共方法

    1. 下拉框实例类 import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang3.Boolean ...

  7. Hello world.java

    Hello world 1.随便新建一个文件夹,存放源代码 2.新建一个Java文件 文件后缀名为.java Hello.java [注意点]系统可能显示没有后缀名,我们需要手动打开 3.编写代码 p ...

  8. Genymotion安装apk问题

    Genymotion安装apk时,出现如下错误: 问题原因分析:很多apk使用arm架构的 cpu,在x86上安装会存在问题. 解决办法: 在Genymotion模拟器上安装一个能够解析ARM架构的a ...

  9. Solon 开发,二、注入或手动获取Bean

    Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...

  10. TextBox,RichTextBox设置行高

    /// <summary> /// 设置行距 /// </summary> /// <param name="ctl">控件</param ...