换钱的最小货币数_补充题目

【补充题目】

给定数组arr,arr中所有的值都为正数。每个值仅代表一张钱的面值,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数。

【举例】

arr=[5,2,3],aim=20
5元、2元和3元的钱各有1张,所以无法组成20元,默认返回-1.
arr=[5,2,5,3],aim=10
5元的货币有2张,可以组成10元,且该方案所需张数最少,返回2.
arr=[5,2,5,3],aim=15
所有的钱加起来才能组成15元,返回4
arr=[5,2,5,3],aim=0
不用任何货币就可以组成0元,返回0

【代码】

    public static void main(String[] args) {
        int[] m={5,2,3};
        int[] n={5,2,5,3};
        //方法1
        System.out.println(minCoins3(m,20));//-1
        System.out.println(minCoins3(n,10));//2
        System.out.println(minCoins3(n,15));//4
        System.out.println(minCoins3(n,0));//0
        //方法2
        System.out.println(minCoins4(m,20));//-1
        System.out.println(minCoins4(n,10));//2
        System.out.println(minCoins4(n,15));//4
        System.out.println(minCoins4(n,0));//0
    } 

    //换钱的最小货币数_补充题目
    public static int minCoins3(int[] arr,int aim){
        if(arr==null||arr.length==0||aim<0){
            return -1;
        }
        int n=arr.length;
        int[][] dp=new int[n][aim+1];
        int max=Integer.MAX_VALUE;
        //dp第一行,只使用一张arr[0],有dp[0][arr[0]]=1,其他为max
        for(int j=1;j<=aim;j++){
            dp[0][j]=max;
        }
        if(arr[0]<=aim){
            dp[0][arr[0]]=1;
        }
        int leftup=0;//左上角某个位置的值
        for(int i=1;i<n;i++){
            for(int j=1;j<=aim;j++){
                leftup=max;
                if(j-arr[i]>=0 && dp[i-1][j-arr[i]]!=max){
                    leftup=dp[i-1][j-arr[i]]+1;
                }
                dp[i][j]=Math.min(leftup, dp[i-1][j]);
        }
            }
        return dp[n-1][aim]!=max?dp[n-1][aim]:-1;       
    }

    //方法2
    public static int minCoins4(int[] arr,int aim){
        if(arr==null||arr.length==0||aim<0){
            return -1;
        }
        int n=arr.length;
        int max=Integer.MAX_VALUE;
        int[] dp=new int[aim+1];
        for(int j=1;j<=aim;j++){
            dp[j]=max;
        }
        if(arr[0]<=aim){
            dp[arr[0]]=1;
        }
        int leftup=0;
        for(int i=1;i<n;i++){
            for(int j=aim;j>0;j--){
            //for(int j=1;j<=aim;j++){ 就不对!
                leftup=max;
                if(j-arr[i]>=0 && dp[j-arr[i]]!=max){
                    leftup=dp[j-arr[i]]+1;
                }
                dp[j]=Math.min(leftup, dp[j]);
            }
        }
        return dp[aim]!=max?dp[aim]:-1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值