3-2 最少硬币问题
问题描述
设有n种不同面值的硬币,各硬币的面值存于数组T[1:n]中。现要用这些面值的硬币来找钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。
对于给定的1≤n≤10,硬币面值数组T和可以使用的各种面值的硬币个数数组Coins,以及钱数m,0≤m≤20001,编程计算找钱m的最少硬币数。
深度优先搜索遍历法(DFS)
Java
public class ZuiShaoYingBi {
//case 1
private static int n = 3;
private static int[] T = {1, 2, 5};
private static int[] coins = {3, 3, 3};
//case 2
// private static int n = 3;
// private static int[] T = {19, 20, 50};
// private static int[] coins = {3, 3, 3};
//case 3
// private static int n = 4;
// private static int[] T = {1, 2, 5, 18};
// private static int[] coins = {3, 3, 3, 1};
//case 4
// private static int n = 4;
// private static int[] T = {1, 2, 5, 18};
// private static int[] coins = {3, 3, 3, 0};
private static int m = 18;
// private static int m = 19;
// private static int m = 20;
// private static int m = 21;
// private static int m = 22;
// private static int m = 23;
// private static int m = 24;
// private static int m = 25;
// private static int m = 0;
// private static int m = 1;
private static int coinsCount = Integer.MAX_VALUE;
private static int tempCount = 0;
public static void main(String[] args) {
dfs(0);
if(coinsCount == Integer.MAX_VALUE || coinsCount == 0)
coinsCount = -1;
System.out.println(coinsCount);
}
private static void dfs(int charge){
if(charge == m && tempCount < coinsCount){
coinsCount = tempCount;
}else if(charge > m){
return;
}else{
for(int i=0; i<n; i++){
if(coins[i] > 0){
coins[i]--;
tempCount++;
dfs(charge+T[i]);
tempCount--;
coins[i]++;
}
}
}
}
}
动态规划法
Java: version 1
public class ZuiShaoYingBi2 {
//case 1
private static int n = 3;
private static int[] T = {0, 1, 2, 5};
private static int[] coins = {0, 3, 3, 3};
//case 2
// private static int n = 3;
// private static int[] T = {0, 19, 20, 50};
// private static int[] coins = {0, 3, 3, 3};
//case 3
// private static int n = 4;
// private static int[] T = {0, 1, 2, 5, 18};
// private static int[] coins = {0, 3, 3, 3, 1};
//case 4
// private static int n = 4;
// private static int[] T = {0, 1, 2, 5, 18};
// private static int[] coins = {0, 3, 3, 3, 0};
private static int m = 18;
// private static int m = 19;
// private static int m = 20;
// private static int m = 21;
// private static int m = 22;
// private static int m = 23;
// private static int m = 24;
// private static int m = 25;
// private static int m = 0;
// private static int m = 1;
private static int[][] c = new int[n+1][m+1];
private static int MAX = 1000000;
private static int coinsCount = MAX;
public static void main(String[] args){
coinsCount = charge();
if(coinsCount == MAX)
coinsCount = -1;
System.out.println(coinsCount);
}
private static int charge(){
int i, j, k;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
c[i][j] = MAX;
for(i=1; i<=n; i++)
c[i][0] = 0;
for(j=1; j<=m; j++)
if(j%T[1] == 0 && j/T[1] <= coins[1])
c[1][j] = j/T[1];
for(i=2; i<=n; i++)
for(j=1; j<=m; j++){
for(k=0; k<=coins[i]; k++)
if(j-k*T[i]>=0 && k+c[i-1][j-k*T[i]] < c[i][j])
c[i][j] = k+c[i-1][j-k*T[i]];
}
return c[n][m];
}
}
Java: version 2
public class ZuiShaoYingBi4 {
//case 1
private static int n = 3;
private static int[] T = {0, 1, 2, 5};
private static int[] coins = {0, 3, 3, 3};
//case 2
// private static int n = 3;
// private static int[] T = {0, 19, 20, 50};
// private static int[] coins = {0, 3, 3, 3};
//case 3
// private static int n = 4;
// private static int[] T = {0, 1, 2, 5, 18};
// private static int[] coins = {0, 3, 3, 3, 1};
//case 4
// private static int n = 4;
// private static int[] T = {0, 1, 2, 5, 18};
// private static int[] coins = {0, 3, 3, 3, 0};
private static int m = 18;
// private static int m = 19;
// private static int m = 20;
// private static int m = 21;
// private static int m = 22;
// private static int m = 23;
// private static int m = 24;
// private static int m = 25;
// private static int m = 0;
// private static int m = 1;
// private static int[][] c = new int[n+1][m+1];
private static int[] c = new int[m+1];
private static int MAX = 1000000;
private static int coinsCount = MAX;
public static void main(String[] args){
coinsCount = charge();
if(coinsCount == MAX)
coinsCount = -1;
System.out.println(coinsCount);
}
private static int charge(){
for(int j=1; j<=m; j++)
c[j] = MAX;
for(int i=1; i<=n; i++)
for(int k=1; k<=coins[i]; k++)
for(int j=m; j>=T[i]; j--)
c[j] = Min(c[j], c[j-T[i]]+1);
return c[m];
}
private static int Min(int a, int b){
return a > b ? b : a;
}
}
Reference
王晓东《计算机算法设计与分析》(第3版)P88

本文介绍了最少硬币找零问题,包括问题描述和两种解决方案:深度优先搜索遍历法(DFS)及动态规划法。提供了Java代码实现,帮助理解算法设计与分析。
737

被折叠的 条评论
为什么被折叠?



