兑换零钱-简单背包问题

题目

题目链接
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.

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

分析

这是一个典型的背包问题,目标是让 货币数最少, arr中的数字至少为1, 最坏情况下需要aim 张1元的货币。
然后看字问题,用dp[i] 表示i元目标最少需要的货币数,那么dp[i] = min(dp[i], dp[i-arr[j]] + 1)。i肯定是从一块一块地来的,所以需要一层循环,同时需要结合数组,所以需要另一层循环。

代码实现

import java.util.*;


public class Solution {
    /**
     * 最少货币数
     * @param arr int整型一维数组 the array
     * @param aim int整型 the target
     * @return int整型
     */
    public int minMoney (int[] arr, int aim) {
        // write code here
        if(aim <1) return 0;
        if(arr.length == 0) return -1;
        int[]dp = new int[aim+1];
        Arrays.fill(dp, aim+1);
        dp[0] = 0;
        // dp[i] = min(dp[i], dp[i-arr[j] + 1])
        for(int i = 1;i <= aim; i++) 
         for(int j = 0;j< arr.length; j++) {
            if(arr[j] <= i) {
                dp[i] = Math.min(dp[i], dp[i-arr[j]] + 1);
            }
         }
         return dp[aim] > aim? -1: dp[aim];
    }
}
posted @ 2022-12-29 21:52  吾日三省吾身-学习  阅读(39)  评论(0)    收藏  举报