文档章节

找硬币和背包问题

Cobbage
 Cobbage
发布于 2013/10/03 00:27
字数 743
阅读 28
收藏 0
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;
    }
}

 

© 著作权归作者所有

共有 人打赏支持
下一篇: 排列与组合
Cobbage

Cobbage

粉丝 49
博文 145
码字总数 72911
作品 1
闵行
QA/测试工程师
私信 提问
js算法初窥05(算法模式02-动态规划与贪心算法)

  在前面的文章中(js算法初窥02(排序算法02-归并、快速以及堆排)我们学习了如何用分治法来实现归并排序,那么动态规划跟分治法有点类似,但是分治法是把问题分解成互相独立的子问题,最...

zaking
05/29
0
0
动态规划之硬币表示问题

问题描述: 有数量不限的硬币,币值为25分、10分、5分和1分,请编写代码计算n分有几种表示法。 求解思路: 这也是典型的动态规划问题,我们可以这样考虑:当只有1分的硬币时,n从1到n分别有多...

一贱书生
2016/11/22
2
0
详解动态规划最少硬币找零问题--JavaScript实现

硬币找零问题是动态规划的一个经典问题,其中最少硬币找零是一个变种,本篇将参照上一篇01背包问题的解题思路,来详细讲解一下最少硬币找零问题。如果你需要查看上一篇,可以点击下面链接: ...

YinTokey
05/27
0
0
CCCC 题目集 L3 001 凑零钱 【背包 + 记录路径 + 思维】

传送门 // 题意: 给定n枚硬币的价值, 给出一个容量m, 问能否恰好在这n个中选择一些硬币使得其价值和加起来等于m, 并输出你选择的这些硬币的价值, 如果有多种选择, 输出字典序最小的那种. 思路...

anxdada
03/10
0
0
Algo-Practice: 算法实践(JavaScript & Java),排序,查找、树、两指针、动态规划等

记录一些算法实践 目录 Java篇 一、基础算法 七种基础排序 二叉堆 K选取问题 链表判环问题 N皇后问题 两指针扫描算法举例 位运算(求首个bit1,求bit1的个数,寻找奇数项) 最小栈的实现 横纵有...

qcer
2017/12/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

[Spring4.x]基于spring4.x纯注解的Web工程搭建

在前文中已经说明了如何基于 Spring4.x+ 版本开发纯注解的非web项目,链接如下: https://my.oschina.net/morpheusWB/blog/2985600 本文则主要说明,如何在Web项目中,"基于spring纯注解方式...

morpheusWB
28分钟前
4
0
基础编程题目集-7-13 日K蜡烛图

股票价格涨跌趋势,常用蜡烛图技术中的K线图来表示,分为按日的日K线、按周的周K线、按月的月K线等。以日K线为例,每天股票价格从开盘到收盘走完一天,对应一根蜡烛小图,要表示四个价格:开...

niithub
44分钟前
3
0
Jenkins window 下的安装使用

1.下载:https://jenkins.io/download/ 双击安装完毕,将自动打开浏览器: http://localhost:8080 打开对应位置的文件,将初始密钥粘贴至输入框。 第一个是 安装默认的软件;第二个是 自定义...

狼王黄师傅
46分钟前
2
0
深入解析react关于事件绑定this的四种方式

这篇文章主要介绍了详解react关于事件绑定this的四种方式,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 在react组件中,每个方...

前端攻城小牛
54分钟前
2
0
JS正则表达式

url的正则表达式:包括IP,域名(domain),ftp,二级域名,域名中的文件,域名加上端口!用户名等等信息 `function` `IsURL(str_url) {``var` `strRegex =``"^((https|http|ftp|rtsp|mm...

前端小攻略
59分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部