有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]); } }