例:
有面值1,3,5分的三种硬币,现在给出一个价值C,问组成价值C最少需要几枚硬币?
16 4 502
4 16**
递归实现
public class Corn {public static void main(String[] args) {int[] arr = {1, 3, 5};int c = 16;int num = func (arr, c);System.out.println ("num:" + num);System.out.println ("number: " + number);}static int number = 0;//记录递归的次数private static int func(int[] arr, int c) {if (c == 0) {return 0;}number++;if (c == 1 || c == 3 || c == 5) {return 1;} else {if (c < 3) {return 1 + func (arr, c - 1);} else if (c < 5) {int n1 = 1 + func (arr, c - 1);int n2 = 1 + func (arr, c - 3);return Math.min (n1, n2);} else {int n1 = 1 + func (arr, c - 1);int n2 = 1 + func (arr, c - 3);int n3 = 1 + func (arr, c - 5);return Math.min (Math.min (n1, n2), n3);}}}}
递归+打表
import java.util.Arrays;
public class Corn2 {
public static void main(String[] args) {
int[] arr = {1,3,5};
int c = 15;
int[] dp = new int[c+1];//记录组成价值i所需要的最少的硬币的数量
Arrays.fill(dp, -1);
int num = func(arr,c,dp);
System.out.println ("num:" + num);
System.out.println ("number" + number);
}
/**
* arr数组放的是硬币,c是指定的价值,返回价值c最少需要的硬币的数量
* @param arr
* @param c
*/
static int number = 0;//计算递归的次数
private static int func(int[] arr, int c,int[] dp) {
if(dp[c] != -1){
return dp[c];
}
number++;
if(c == 0){
dp[c] = 0;
return 0;
}
if(c == 1 || c == 3 || c == 5){
dp[c] = 1;
return 1;
}else {
if(c < 3){
dp[c] = 1 + func (arr,c-1,dp);
}else if(c < 5){
int n1 = 1 + func (arr,c-1,dp);
int n2 = 1 + func (arr,c-3,dp);
dp[c] = Math.min (n1,n2);
}else{
int n1 = 1 + func (arr,c-1,dp);
int n2 = 1 + func (arr,c-3,dp);
int n3 = 1 + func (arr,c-5,dp);
dp[c] = Math.min (Math.min (n1,n2),n3);
}
return dp[c];
}
}
}
递推实现
import java.util.Arrays;
public class Corn2 {
public static void main(String[] args) {
int[] v = {1, 3, 5};
int c = 16;
int number = 0;
int[] dp = new int[c + 1];
for (int i = 1; i <= c; i++) {
dp[i] = i;
for (int j = 0; j < v.length; j++) {
number++;
if (i >= v[j] && 1 + dp[i - v[j]] < dp[i]) {
dp[i] = 1 + dp[i - v[j]];
}
}
}
System.out.println ("num:" + dp[c]);
System.out.println ("number:" + number);
}
}
