有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n<10000),求组合n分钱所需要的最少硬币数?

有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n<10000),求组合n分钱所需要的最少硬币数?

动态规划的典型例题,首先定义dp[n],存放从0-n所需要的最小硬币数,v[i]存放硬币的面值,初始化dp[0] = 0,得出状态转移方程dp[i]=min{dp[i-1]+1,dp[i-v[j]] +1 },且i-1>=0&&i-v[j]>=0。

public class MinimumCoins {
    public void dfs(int v[],int n){
        int dp[] = new int[n];
        dp[0] = 0;
        int j = 0;
        for(int i = 1;i<n;i++){
            if(i==1){
                j = 0;
            }
            if(i==2){
                j =1;
            }
            if(i==3){
                j = 2;
            }
            if(i==5){
                j=3;
            }
            if(i-1>=0&&i-v[j]>=0){
                dp[i] = dp[i-1]+1<dp[i-v[j]]+1?dp[i-1]+1:dp[i-v[j]]+1;
            }

        }
        System.out.println("最少需要硬币数:"+dp[n-1]);
    }
    public static void main(String[] args) {
        MinimumCoins m = new MinimumCoins();
        int[] v = {1,2,4,5};
        m.dfs(v,12);
    }
}
public class MinimumCoins {
    int n = 1;
    public int dp[] = new int[n+1];
    int len = 4; //len是v的长度
    int v[] ={1,2,4,5};
    //递归实现  数组dp首先出第0位为0,其他位置都为-1
    public int dfs(int n){
        if(dp[n]!=-1){
            return dp[n];
        }
        dp[n] = 11;
        for(int j=0;j<len;j++){
            if(n-v[j]>=0)
            {
                dp[n] = min(dp[n],dfs(n-v[j])+1);
            }
        }
        return dp[n];
    }
    public int min(int a,int b){
        return a<b?a:b;
    }

    public static void main(String[] args) {
        MinimumCoins m = new MinimumCoins();
        for(int i =1;i<m.dp.length;i++){
            m.dp[i] =-1;
        }
        m.dfs(m.n);
        System.out.println(m.dp[m.n]);
    }
}
原文地址:https://www.cnblogs.com/menbo/p/11365298.html