动态规划--找零钱 coin change
来自http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
对于整数N,找出N的所有零钱的表示。零钱可以用S={s1,s2,s3,..sm}表示,每种零钱的数量为无穷。请问有多少种找零的方法?
例如,
N = 4,S = {1,2,3},有四种找零方式{1,1,1,1},{1,1,2},{2,2},{1,3},return 4
N = 10,S= {2,5,3,6} ,有5中找零方式{2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5} return 5;
============
递归方法,利用搜索树
1,找出子问题模型:为了统计所有s结果的数量,我们可以将问题分为两部分: 结果中不含有硬币sm, 结果中含有硬币sm
函数int count(int S[],int m,int n)计算结果的数量,
函数返回 S[0..m-1]组成的零钱 可以为N找零钱的 方法数
那么很显然可以等价于这两者的和 count(S,m-1,n) + count(S,m,n-S[m-1]),其中count[S,m-1,n]不包括S[m-1]这个硬币,count(S,m,n-S[m-1])包括了S[m-1]这个硬币。
==
迭代计算子问题,使用递归的方法:
代码的注释是为了求解有多少找零钱的方法,
code的方法是为了求解所有结果,打印出来
class A{
public:
///returns the count of ways we can sum s[0..m-1] coins to get sum n
void help_coinChange(vector<int>& s,int m,int n,vector<int> re){
/// if n is 0 then this is 1 solution (do not include any coin)
if(n==){
for(auto i: re){cout<<i<<" ";}cout<<"-"<<endl;
return;
}
/// if n is less than 0 then no solution exists
if(n<) return;
/// if there are no coins and n is greater than 0, there no solution exist
//if(m=0 && n>=1) return ;
if(m<=) return ;
///(i) excluding S[m-1] (ii) including S[m-1]
help_coinChange(s,m-,n,re);
re.push_back(s[m-]);
help_coinChange(s,m,n-s[m-],re);
}
void coinChange(vector<int>& coins, int amount){
vector<int> re;
help_coinChange(coins,coins.size(),amount,re);
}
};
这种方法可以画成一颗DFS搜索树
例如:
c[,,],m=,n=,re=[]
/ \
c[],m=,n=,[]
/ \
c[],m=,n=,[]
/ \
c[],m=,n=,[] c[],m=,n=,[]
/ \
c[],m=,n=,[] c[],m=,n=,[,]
/ \
c[],m=,n=,[,] c[],m=,n=,[,,]
/ \
c[],m=,n=,[,,] c[],m=,n=,[,,,]
/ \
c[],m=,n=,[,,,] c[],m=1,n=0,[1,1,1,1,1]====
这么搜索,会有很多重复的路径在里面。
当然我们也可以采用BFS的方法来求解 http://bookshadow.com/weblog/2015/12/27/leetcode-coin-change/
代码在这里,
==================完全背包问题,动态规划
这个在在背包问题9讲里讲的很详细,可以google一下。
代码在这里(统计找零钱的种类数)
class A{
public:
void dp_coinChange(vector<int> & coins,int amount){
vector<int> re;
int n = amount;///
int m = coins.size();
vector<int> re1;
vector<int> re2;
///we need n+1 rows as the table is constructed in bottom up manner
/// using the base case 0 value case (n=0)
int table[n+][m];
///fill the enteries for 0 value case (n = 0)
for(int i = ;i<m;i++){
table[][i] = ;
}
///fill rest the table enteries in bottom up manner
for(int i = ;i< n+;i++){
for(int j = ;j<m;j++){
///count of solutions including S[j]
int x = (i-coins[j] >=)? table[i-coins[j]][j]:;
///count of solutions excluding S[j]
int y = (j >= )?table[i][j-]:;
///total count
table[i][j] = x+y;
}cout<<endl;
}
//return table[n][m-1];
}
};
==================================
动态规划寻找零钱个数最少的解。leetecode 322
给定几个固定的面值,可以无限使用。一个目标数,要求用最少的硬币兑换这个target
解法1,如果每次走给定面值的步数,问对少走多少步能达到目标target,可以使用bfs的思路求解。
解法2,动态规划:dp[i] = min{dp[i-c1],dp[i-c2],dp[i-c3],dp[i-c4]...}+1
class Solution {
public:
int coinChange(vector<int>& coins, int amount){
///dp[i] = min{dp[i-c1],dp[i-c2],dp[i-c3],dp[i-c4]...}+1
if(amount == ) return ;
vector<int> dp(amount+,INT_MAX);
dp[] = ;
for(int i = ;i<amount+;i++){
for(int j = ;j<(int)coins.size();j++){
if(i-coins[j]>=){
dp[i] = min(dp[i],dp[i-coins[j]]);
}
}
int tmp = (dp[i]==INT_MAX)? INT_MAX: dp[i]+;
dp[i] = tmp;
}
return dp[amount]==INT_MAX? -: dp[amount];
}
};
动态规划--找零钱 coin change的更多相关文章
- [LeetCode] Coin Change 硬币找零
You are given coins of different denominations and a total amount of money amount. Write a function ...
- [LeetCode] 322. Coin Change 硬币找零
You are given coins of different denominations and a total amount of money amount. Write a function ...
- [LeetCode] 518. Coin Change 2 硬币找零 2
You are given coins of different denominations and a total amount of money. Write a function to comp ...
- python---通过递归和动态规划策略解决找零钱问题
也是常见套路. # coding = utf-8 def rec_mc(coin_value_list, change, know_results): min_coins = change if ch ...
- 后台开发 3个题目 array_chunk, 100块钱找零钱(动态规划 dynamic programming), 双向循环链表 llist 删除节点
1. array_chunk 实现 http://php.net/manual/en/function.array-chunk.php <?php function my_array_chunk ...
- [LeetCode] Coin Change 2 硬币找零之二
You are given coins of different denominations and a total amount of money. Write a function to comp ...
- [LeetCode] 518. Coin Change 2 硬币找零之二
You are given coins of different denominations and a total amount of money. Write a function to comp ...
- [LeetCode] 由 “找零钱" 所想
Ref: [Optimization] Dynamic programming[寻找子问题] Ref: [Optimization] Advanced Dynamic programming[优于re ...
- JSU省赛队员选拔赛个人赛1(Coin Change、Fibbonacci Number、Max Num、单词数、无限的路、叠筐)
JSU省赛队员选拔赛个人赛1 一.题目概述: A.Coin Change(暴力求解.动态规划) B.Fibbonacci Number(递推求解) C.Max Num(排序.比较) D.单词数 ...
随机推荐
- Bezier贝塞尔曲线的原理、二次贝塞尔曲线的实现
Bezier曲线的原理 Bezier曲线是应用于二维图形的曲线.曲线由顶点和控制点组成,通过改变控制点坐标可以改变曲线的形状. 一次Bezier曲线公式: 一次Bezier曲线是由P0至P1的连续点, ...
- Python风格规范-FYI
Python风格规范 分号 Tip 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 行长度 Tip 每行不超过80个字符 例外: 长的导入模块语句 注释里的URL 不要使用反斜杠连接行. Py ...
- WQS二分学习笔记
前言 \(WQS\)二分听起来是个很难的算法,其实学起来也并不是那么难. 适用范围 在某些题目中,会对于某个取得越多越优的物品,限定你最多选择\(k\)个,问你能得到的最优答案. 例如这道题目:[CF ...
- EL和JSTL表达式学习记录
EL.JSTL表达式EL:1.EL使用目的:代替jsp页面中java脚本编写 2.EL作用:(1)从域中取出数据(最重要)(2)EL的内置对象(11个)(3)EL可以执行表达式运算 JSTL(JSP标 ...
- Bootstrap历练实例:按钮(Button)插件单个切换
单个切换 如需激活单个按钮的切换(即改变按钮的正常状态为按压状态,反之亦然),只需向 button 元素添加 data-toggle="button" 作为其属性即可,如下面实例所 ...
- 操作系统(2)_进程管理_李善平ppt
所有程序都有CPU和io这两部分,即使没有用户输入也有输出. CPU最好特别忙,io空闲无所谓. 程序/数据/状态 三个维度来看进程. 等待的资源可能是io资源或者通信资源(别的进程的答复). 一个进 ...
- Vue之Vue-touch的使用
最近项目中,有的页面发现设置返回键看起来怪怪的,感觉与整体不协调,于是就考虑使用手势滑动事件来实现返回功能~ 开叉查阅资料~找到了vue-touch,使用起来可谓是简单粗暴啊,适合我这样的快速开发人员 ...
- 数据库引擎InnoDB和myisam的区别和联系
1.ENGINE=InnoDB 数据库存储引擎,DEFAULT 默认,CHARSET=utf8 数据库字符编码 2.数据库的存储引擎, mysql中engine=innodb和engine=myisa ...
- pyhon之99乘法表
1.长方形完整格式 for i in range(1,10): for j in range(1,10): print("%d*%d" %(j,i),end=" &quo ...
- Vue 使用History记录上一页面的数据
UI Mvvm 前端数据流框架精讲 Vue数据双向绑定探究 面试问题:Vuejs如何实现双向绑定 数据双向绑定的探究和实现 需求 从列表页的第二页进入详情页,返回时列表页仍然显示在第二页: 从列表页的 ...