循环方式正向来解:
public static void main(String[] args) {
/**
* 拥有的硬币数额
*/
int[] coinValue = new int[] { 25, 21, 10, 5, 1 };
/**
* 要破开的数额
*/
int money = 63;
/**
* 存储已经有的钱数最优解 0位置存储需要的硬币数目
*/
int[][] coinsUsed = new int[money + 1][coinValue.length+1];
/**
* 计算
*/
makeChange(coinValue, coinValue.length, money, coinsUsed);
}
private static void makeChange(int[] coinValue, int length, int money, int[][] coinsUsed) {
/**
* 0元的最优解就是0
*/
coinsUsed[0][0] = 0;
/**
* 从1开始计算最优解
*/
for(int i=1;i<=money;i++){
/**
* 用1元来计算多少个硬币
*/
coinsUsed[i][0] = i;
for(int j = 0;j<coinValue.length;j++){
int c = coinValue[j];
if(c<=i){
/**
* 1是表示当前的硬币,coinsUsed[i-c]是之前的最优解
*/
int temp = i-c;
int min = coinsUsed[temp][0]+1;
if(min<=coinsUsed[i][0]){
coinsUsed[i][0]= min;
for(int m=0;m<coinValue.length;m++){
if(m==j){
coinsUsed[i][m+1] = coinsUsed[temp][m+1]+1;
}else {
coinsUsed[i][m+1] = coinsUsed[temp][m+1];
}
}
}
}
}
System.out.println("面值为 " + (i) + " 的最小硬币数 : " + coinsUsed[i][0]+ " 25 元面值 : " + coinsUsed[i][1]+ " 21 元面值: " + coinsUsed[i][2]+ " 10 元面值: " + coinsUsed[i][3]+ " 5 元面值: " + coinsUsed[i][4]+ " 1 元面值: " + coinsUsed[i][5]);
}
}
迭代方式逆向来解:
private static int[] coinValue;
private static int[][] coinsUsed ;
public static void main(String[] args) {
/**
* 拥有的硬币数额
*/
coinValue = new int[] { 25, 21, 10, 5, 1 };
/**
* 要破开的数额
*/
int money = 63;
/**
* 存储已经有的钱数最优解 0位置存储需要的硬币数目
*/
coinsUsed = new int[money + 1][coinValue.length+1];
/**
* 计算
*/
// makeChange(coinValue, coinValue.length, money, coinsUsed);
getYouJie(money);
}
private static void makeChange(int[] coinValue, int length, int money, int[][] coinsUsed) {
}
private static int[] getYouJie(int money){
if(money==1){
int md = 1;
}
if(money==0){
return coinsUsed[0];
}
if(coinsUsed[money][0]!=0){
return coinsUsed[money];
}
int[] min = coinsUsed[money];
min[0] = money;
for(int i=0;i<coinValue.length;i++){
if(money>=coinValue[i]){
int[] coin = getYouJie(money-coinValue[i]);
/**
* 之前的硬币数目加1
*/
int m = coin[0]+1;
if(m<=min[0]){
min[0] = m;
for(int k=1;k<min.length;k++){
if(k-1==i){
min[k] = coin[k]+1;
}else {
min[k] = coin[k];
}
}
}
}
}
System.out.println("面值为 " + (money) + " 的最小硬币数 : " + coinsUsed[money][0]+ " 25 元面值 : " + coinsUsed[money][1]+ " 21 元面值: " + coinsUsed[money][2]+ " 10 元面值: " + coinsUsed[money][3]+ " 5 元面值: " + coinsUsed[money][4]+ " 1 元面值: " + coinsUsed[money][5]);
return min;
}