最少硬币问题

假设有3种不同的硬币,币值分别是CoinValue[] = {1, 2, 5},每一种硬币的数量是有限的,分别是CoinNum[] = {3, 3, 3},给定一个数值target=18,找出一种硬币数最少的方法, 输出最少的硬币数。

思路:我们考虑用动态规划解决这个问题,动态规划的基本宗旨是:无后效性,他只能利用先前的知识来推导出后面的知识。最重要的是要有状态转移方 程。我们可以把大问题化为小问题,从局部问题求解。

假如:我们选取dp(i)表示存够i元最少需要的硬币数。

dp(0) = 0: 表示存够0元最少需要0枚硬币

dp(1)=1:首先找到小于等于1的硬币,发现只有1,选取此枚硬币,只需找到凑够0元需要的最少硬币数,即dp(1) = dp(1-1)+1=1(此处加1表示因为所求的是硬币的数量,开始处已经选取了1枚硬币,所以需要把这个1加上。)

dp(2)=2:首先找到小于等于2的硬币,发现有1、2,先选取1这枚硬币,只需找到凑够1元需要的最少硬币数,即dp(2)=dp(2-1)+1=dp(1)+1=2,也可以是选取2这枚硬币,只需找到凑够0元需要的最少硬币数,即dp(2)=dp(2-2)+1=dp(0)+1=1,由于,我们需要找的是凑够2元的最少硬币数,所以,我们需要在2和1之间取一个最小值,即Math.min{dp(2-1)+1,dp(2-2)+1}。

以下情况类似。

从以上可以发现:状态转移方程:dp(i) = Math.min{dp(i-coinValue(j))+1},coinValue()表示存储的硬币种类。

需要注意的是:假设我们需要i元的最少硬币数,我们需要构建一个i+1的数组,存储dp(0) = 0,因为dp(i)从1存储,有dp(i-1)。

import java.util.*;

public class MinCoin {
	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		while(scan.hasNext()){
			int totalPrice = scan.nextInt();
			int number = scan.nextInt();
			int[] value = new int[number];
			for(int i=0;i<number;i++){
				value[i] = scan.nextInt();
			}
			int[] type = new int[totalPrice+1];
			type[0] = 0;
			int minType = 0;
			for(int i=1;i<totalPrice+1;i++){
				minType = i;
				for(int j=0;j<value.length;j++){
					if((value[j]<=i)&&(type[i-value[j]]+1)<minType){
						minType = type[i-value[j]]+1;
					}
				}
				type[i] = minType;
			}
			System.out.println(type[totalPrice]);
		}
	}
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值