首页 > 试题广场 >

换钱的最少货币数

[编程题]换钱的最少货币数
  • 热度指数:8775 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。

输入描述:
输入包括两行,第一行两个整数n(0<=n<=1000)代表数组长度和aim(0<=aim<=5000),第二行n个不重复的正整数,代表arr


输出描述:
输出一个整数,表示组成aim的最小货币数,无解时输出-1.
示例1

输入

3 20
5 2 3

输出

4

说明

20=5*4
示例2

输入

3 0
5 2 3

输出

0
示例3

输入

2 2
3 5

输出

-1

备注:
时间复杂度,空间复杂度
import java.io.*;

public class Main{
    
    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] s = reader.readLine().split(" ");
        int n = Integer.valueOf(s[0]);
        int target = Integer.valueOf(s[1]);
        int[] dp = new int[target+1];
        int[] arr = new int[n];
//         dp[i] = max(dp[target-arr[0]],dp[target-arr[1]],...)
        s = reader.readLine().split(" ");
        for(int i=0;i<n;i++){
            arr[i] = Integer.valueOf(s[i]);
        }
        for(int i=1;i<target+1;i++){
            int tmp = -1;
            for(int j=0;j<n;j++){
                if(i-arr[j] < 0 || dp[i-arr[j]] == -1){
                    continue;
                }
                else {
                    if(tmp==-1)
                        tmp = dp[i-arr[j]] + 1;
                    tmp = Math.min(dp[i-arr[j]]+1,tmp);
                }
                    
            }
            dp[i]  = tmp;
        }
        System.out.println(dp[target]);
        
    }
}
发表于 2022-08-11 22:34:34 回复(0)
import java.io.*;
import java.util.Arrays;
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] str = reader.readLine().split(" ");
        int[] arr = parse(str,2);
        int n = arr[0];
        int amount = arr[1];
        arr = parse(reader.readLine().split(" "),n);
        reader.close();
        System.out.println(coinChange(arr,amount));
    }
    private static int coinChange(int[] coins, int amount) {
        int max = amount + 1;
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, max);
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            for (int j = 0; j < coins.length; j++) {
                if (coins[j] <= i) {
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
    
    private static int[] parse(String[] str,int len){
        int[] arr = new int[len];
        for(int i= 0;i < len;++i){
            arr[i] = Integer.parseInt(str[i]);
        }
        return arr;
    }
}

发表于 2021-01-29 13:41:21 回复(0)

转化为完全背包:
aim--->背包容量
每种货币的面值--->每种物品的体积
货币数--->每种物品的价值
问题就转为:求背包容量恰好为 aim 时的最小价值
因为是恰好,所以初始化dp时要置为无穷,dp[0] = 0

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static int INF = Integer.MAX_VALUE >> 1;
    static int N = 5010;
    static int n, aim;
    static int[] g = new int[N];
    static int[] dp = new int[N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        aim = sc.nextInt();
        Arrays.fill(dp, INF);
        dp[0] = 0;
        for (int i = 0; i < n; i++) {
            g[i] = sc.nextInt();
            for (int j = g[i]; j <= aim; j++) {
                dp[j] = Math.min(dp[j], dp[j - g[i]] + 1);
            }
        }
        if (dp[aim] == INF) dp[aim] = -1;
        System.out.println(dp[aim]);
    }
}
发表于 2020-07-05 10:53:36 回复(0)
以示例1输入为例:



时间复杂度O(n*aim),空间复杂度压缩至O(aim)。

import java.util.*;

public class P189 {

    public static int process(int[] arr, int N, int aim) {
        int[] dp = new int[aim + 1];
        Arrays.fill(dp, -1);
        dp[0] = 0;
        for (int i = N - 1; i >= 0; i--) {
            for (int rest = 0; rest <= aim; rest++) {
                if (rest - arr[i] >= 0 && dp[rest - arr[i]] != -1) {
                    if (dp[rest] != -1) {
                        dp[rest] = Math.min(dp[rest], dp[rest - arr[i]] + 1);
                    } else {
                        dp[rest] = dp[rest - arr[i]] + 1;
                    }
                }
            }
        }
        return dp[aim];
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int aim = sc.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = sc.nextInt();
        }
        System.out.println(process(arr, N, aim));
    }
}
发表于 2020-05-13 07:07:22 回复(0)