博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
左神算法进阶班7_2换钱组合数
阅读量:4541 次
发布时间:2019-06-08

本文共 3585 字,大约阅读时间需要 11 分钟。

【题目】

给定数组arr,arr中所有的值都为正数且不重复。

每个值代表一种面值的货币,每种面值的货币可以使用任意张,

再给定一个整数aim代表要找的钱数,求换钱有多少种方法。

【举例】

arr = [5, 10, 25, 1],aim = 0。

组成0元的方法有1种,就是所有面值的货币都不用。所以返回1。

arr = [5, 10, 25, 1],aim = 15。

组成15元的方法有6种,分别为3张5元、1张10元 + 1张5元、1张10元 + 5张1元、10张1元 + 1张5元、2张5元 + 5张1元和15张1元。所以返回6。

arr = [3, 5],aim = 2。

任何方法都无法组成2元。所以返回0

【题解】

1、暴力解法:

使用递归,判断每种面值的钱使用不同数量的组合总数

2、使用动态规划法

【代码】

  

1 #include 
2 #include
3 4 using namespace std; 5 6 ///纯递归法 7 int process1(vector
v, int index, int aim) 8 { 9 int res = 0; 10 if (index == v.size()) 11 res = aim == 0 ? 1 : 0; 12 else 13 { 14 for (int i = 0; v[index] * i <= aim; ++i) 15 res += process1(v, index + 1, aim - v[index] * i); 16 } 17 return res; 18 } 19 20 int coins1(vector
v, int aim) 21 { 22 if (v.size() == 0 || aim < 0) 23 return 0; 24 return process1(v, 0, aim); 25 } 26 27 ///自顶向下的备忘录 28 int process2(vector
v, int index, int aim, vector
>dp) 29 { 30 int res = 0; 31 if (index == v.size()) 32 res = aim == 0 ? 1 : 0; 33 else 34 { 35 int val = 0; 36 for (int i = 0; v[index] * i <= aim; ++i) 37 { 38 val = dp[index + 1][aim - v[index] * i]; 39 if (val != 0) 40 res += val == -1 ? 0 : val; 41 else 42 res += process2(v, index + 1, aim - v[index] * i, dp); 43 } 44 } 45 dp[index][aim] = res == 0 ? -1 : res; 46 return res; 47 } 48 49 int coins2(vector
v, int aim) 50 { 51 if (v.size() == 0 || aim < 0) 52 return 0; 53 vector
>dp(v.size() + 1, vector
(aim + 1, 0)); 54 return process2(v, 0, aim, dp); 55 } 56 57 ///自底向上法 58 59 int process3(vector
v, int aim) 60 { 61 vector
>dp(v.size(), vector
(aim + 1, 0)); 62 for (int i = 0; i < v.size(); ++i) 63 dp[i][0] = 1; 64 for (int j = 1; v[0] * j <= aim; ++j) 65 dp[0][v[0] * j] = 1;//就是第一种面额最高能使用多少张? 66 for(int i=1;i
= 0; ++k) 71 num += dp[i - 1][j - v[i] * k]; 72 dp[i][j] = num; 73 } 74 75 return dp[v.size() - 1][aim]; 76 } 77 78 int process4(vector
v, int aim) 79 { 80 vector
>dp(v.size(), vector
(aim + 1, 0)); 81 for (int i = 0; i < v.size(); ++i) 82 dp[i][0] = 1; 83 for (int j = 1; v[0] * j <= aim; ++j) 84 dp[0][v[0] * j] = 1;//就是第一种面额最高能使用多少张? 85 for (int i = 1; i < v.size(); ++i) 86 for (int j = 1; j <= aim; ++j) 87 { 88 dp[i][j] = dp[i - 1][j]; 89 dp[i][j] += j - v[i] >= 0 ? dp[i][j - v[i]] : 0; 90 } 91 return dp[v.size() - 1][aim]; 92 } 93 94 int process5(vector
v, int aim) 95 { 96 vector
dp(aim + 1, 0); 97 for (int j = 0; v[0] * j <= aim; ++j) 98 dp[v[0] * j] = 1;//就是第一种面额最高能使用多少张? 99 for (int i = 1; i < v.size(); ++i)100 for (int j = 1; j <= aim; ++j)101 dp[j] += j - v[i] >= 0 ? dp[j - v[i]] : 0;102 103 return dp[aim];104 }105 106 int coins3(vector
v, int aim)107 {108 if (v.size() == 0 || aim < 0)109 return 0; 110 return process3(v, aim);111 }112 113 void Test()114 {115 vector
v;116 int aim;117 v = { 5, 10, 25, 1 };118 aim = 0;119 cout << coins1(v, aim) << endl;120 121 v = { 5, 10, 25, 1 };122 aim = 15;123 cout << coins2(v, aim) << endl;124 125 v = { 3,5 };126 aim = 2;127 cout << coins1(v, aim) << endl;128 }

 

转载于:https://www.cnblogs.com/zzw1024/p/11095413.html

你可能感兴趣的文章
hdu 1704 Rank(floyd传递闭包)
查看>>
Educational Codeforces Round 27 G. Shortest Path Problem?(Guass异或线性基)
查看>>
【BZOJ3622】已经没有什么好害怕的了(动态规划+广义容斥)
查看>>
HDOJ 1023 Train Problem II
查看>>
途牛订单的服务化演进
查看>>
软件工程之四则运算
查看>>
ABAP 根据权限显示或隐藏状态栏的按钮
查看>>
跑步计划
查看>>
mvc中使用uploadify批量上传的应用
查看>>
Kibana查询说明
查看>>
[AHOI 2009]chess 中国象棋
查看>>
UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
查看>>
Hibernate学习四----------Blob
查看>>
CTF-练习平台-Misc之 中国菜刀,不再web里?
查看>>
Mac系统配置JDK环境变量
查看>>
多项式累加
查看>>
剑指offer(18)二叉搜索树的后续遍历
查看>>
微信小程序一笔记账开发进度四
查看>>
bzoj 1070 费用流
查看>>
201671010139 徐楠 第四周总结
查看>>