public class Coin {
public static void getCoinMethod(int[]coins,int[] vesult,int money){
for(int i=1;i<=money;i++){
int min=i;
for(int j=1;j<coins.length;j++){
if(coins[j]<=i){
int temp=vesult[i-coins[j]]+1;
if(temp<min)min=temp;
}
}
vesult[i]=min;
System.out.println(i+"需要组合个数:"+min);
}
}
public static void main(String[] args) {
int[]coins=new int[]{0,1,2,3,4,5,10,21,25};
int money=50;
int[]vesult=new int[money+1];
getCoinMethod(coins,vesult,money);
System.out.println("========================");
System.out.println(Arrays.toString(coins));
for(int i=1;i<=50;i++){
int[][]result=new int[coins.length][i+1];
getCoinMethod(coins,result,i);
}
}
public static void getCoinMethod(int[]coins,int[][]result,int money){
//result是一个二维的数组
// x标示coin的种类,y标示的结果的大小
for(int init=1;init<=money;init++){
result[1][init]=init;
}
for(int i=2;i<coins.length;i++){
for(int j=1;j<=money;j++){
result[i][j]=result[i-1][j];
int count=j/coins[i];
for(int k=0;k<=count;k++){
if(result[i][j]>result[i-1][j-k*coins[i]]+k)
result[i][j]=result[i-1][j-k*coins[i]]+k;
}
}
//System.out.println(Arrays.toString(result[i]));
}
System.out.println(money+"组合数:");
for(int n=coins.length-1;n>0;n--){
int count=money/coins[n];
if(money>=coins[n]&&result[n][money]==(result[n-1][money-coins[n]*count]+count)){
money=money-coins[n]*count;
System.out.print(coins[n]+":"+count+"个 +");
}
}
System.out.println();
}
}
结果的组合可能不是唯一的,转换为动态规划树的问题
public class MinCoins {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] coins={1,3,5};
int value=100;
int[] solu=new int[value];
int min=new MinCoins().solution(coins,value,solu);
for(int i=value-1;i>=0;){
System.out.print(solu[i]+"->");
i=i-solu[i];
}
System.out.println();
System.out.println(min);
}
private int solution(int[] coins,int value, int[] solu){
int[] mins = new int[value+1];
mins[0]=0;
for(int i=1;i<=value;i++) mins[i]=Integer.MAX_VALUE;
for(int i=1;i<=value;i++){
for(int j=0;j<coins.length;j++){
if(coins[j]<=i&&mins[i]>mins[i-coins[j]]+1){
mins[i]=mins[i-coins[j]]+1;
solu[i-1]=coins[j];
}
}
}
return mins[value];
}
}
public class BackPack {
public static void main(String[] args) {
int m = 10;
int n = 3;
int w[] = {3, 4, 5};
int p[] = {4, 5, 6};
int c[][] = BackPack_Solution(m, n, w, p);
for (int i = 1; i <=n; i++) {
for (int j = 1; j <=m; j++) {
System.out.print(c[i][j]+"\t");
if(j==m){
System.out.println();
}
}
}
//printPack(c, w, m, n);
}
/**
* @param m 表示背包的最大容量
* @param n 表示商品个数
* @param w 表示商品重量数组
* @param p 表示商品价值数组
*/
public static int[][] BackPack_Solution(int m, int n, int[] w, int[] p) {
//c[i][v]表示前i件物品恰放入一个重量为m的背包可以获得的最大价值
int c[][] = new int[n + 1][m + 1];
for (int i = 0; i < n + 1; i++)
c[i][0] = 0;
for (int j = 0; j < m + 1; j++)
c[0][j] = 0;
for (int i = 1; i < n + 1; i++) {
for (int j = 1; j < m + 1; j++) {
//当物品为i件重量为j时,如果第i件的重量(w[i-1])小于重量j时,c[i][j]为下列两种情况之一:
//(1)物品i不放入背包中,所以c[i][j]为c[i-1][j]的值
//(2)物品i放入背包中,则背包剩余重量为j-w[i-1],所以c[i][j]为c[i-1][j-w[i-1]]的值加上当前物品i的价值
if (w[i - 1] <= j) {
if (c[i - 1][j] < (c[i - 1][j - w[i - 1]] + p[i - 1]))
c[i][j] = c[i - 1][j - w[i - 1]] + p[i - 1];
else
c[i][j] = c[i - 1][j];
} else
c[i][j] = c[i - 1][j];
}
}
return c;
}
}