牛客刷题——找零最少

题目:给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。

eg:输入:[5,2,3],20   ,输出:4

动归是硬伤啊,还是不会做。

思路应该是对的,针对已有的面值,对前面的每个状态 j 进行计算,但是动归方程到底啥时候用一维啥时候用二维啊....

首先将所有的元素初始化为 Integer.MAX_VALUE-1,然后将 dp[0] 置为0,因为当找零为0时,所需要的数量为0,然后对后面每一数值,首先判断能不能用,即当前面值是否是小于找零钱数的,如果可用的话,使用 min 来决定用不用,不用的话就还是保持现状,用的话,这里只考虑用一张,所以为数量为 dp[i-arr[j]]+1,两者取个最小,(考虑只用一张其实是将问题分解了,比如4的时候,遇到2,用一张,就转换成找2,这个问题已经解决过了)最后在返回的时候判断一下值是不是 Integer.MAX_VALUE-1,是的话return -1,否则return 对应的值。

完整代码如下:

public static  int minMoney (int[] arr, int aim) {
        // write code here
		if(aim==0) {
			return 0;
		}
		if(arr.length==0) {
			return -1;
		}
		int[] dp = new int[aim+1];
		Arrays.fill(dp, Integer.MAX_VALUE-1);
		dp[0]=0;//需要找0元
		for(int i=0;i<aim+1;i++) {
			for(int j=0;j<arr.length;j++) {
				if(arr[j]<=i) {//可以用  不用的话就保持原来的数据,用的话就进行更新
					dp[i] = Math.min(dp[i], dp[i-arr[i]]+1);
				}
			}
		}
		return dp[aim]==Integer.MAX_VALUE-1?-1:dp[aim];
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值