动态规划——硬币找零和币值最大化问题
一、硬幣找零問題
1.問題
有面值為1元、3元和5元的硬幣若干枚,給定一個輸入面額,問如何采用最少的硬幣數(shù)目,得到當(dāng)前面額
2.思路
找出狀態(tài)轉(zhuǎn)移方程,每次可以拿取1元、3元或者5元的硬幣,每次拿取,硬幣數(shù)加1,用d[v]表示當(dāng)前面額為v的最小硬幣數(shù)目,
d[0]=0;? //硬幣數(shù)為0,不拿??
d[1]=d[1-1]+1 ;? ?//硬幣數(shù)為1,只能拿取1元的硬幣,相應(yīng)的當(dāng)前硬幣數(shù)加1
d[2]=d[2-1]+1;? ?//硬幣是為2,只能拿取1元的硬幣,相應(yīng)的當(dāng)前硬幣數(shù)加1
d[3]=d[3-1]+1 或者 d[3-3]+1;? ? //有兩種拿法,一種拿1元的,一種拿3元的,每次拿取硬幣數(shù)加1,要求最小數(shù),比較兩種的硬幣數(shù)目,分別為3和1,因此采取第二種拿法,d[3]=min{d[3-1]+1,d[3-3]+1}
d[5]=d[5-1]+1、d[5-3]+1、d[5-5]+1,三種拿法,d[5]=min{d[3-1]+1,d[3-3]+1,d[5]=d[5-5]+1},最小數(shù)目為1
.........以此類推
d[v]=min{d[v-1]+1,d[v-3]+1,d[v-5]+1},其中v>=0,v<0時,不算入硬幣數(shù)
3.代碼如下所示
public class Main {public static int way(int d[],int n){for (int i = 1; i <=n ; i++) {int k1=Integer.MAX_VALUE,k3=Integer.MAX_VALUE,k5=Integer.MAX_VALUE;if (i-1>=0) //拿取面值為1的硬幣,面額減1,數(shù)量相應(yīng)的加1k1=d[i-1]+1;if (i-3>=0) //拿取面值為3的硬幣,面額減3,數(shù)量相應(yīng)的加1k3=d[i-3]+1;if (i-5>=0) //拿取面值為5的硬幣,面額減5,數(shù)量相應(yīng)的加1k5=d[i-5]+1;//得到當(dāng)前組成面額的最少硬幣數(shù)int min1=Math.min(k1,k3);d[i]=Math.min(min1,k5);System.out.println("面值為"+i+"最少硬幣數(shù)為:"+d[i]);}return d[n];}public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int d[]=new int[n+1];int k=way(d,n);System.out.println("最少硬幣數(shù)量為:"+k);} }4.實(shí)驗(yàn)結(jié)果
輸入15
二、幣值最大化問題
1.題目
給定一排n枚硬幣,面值為正整數(shù)c1,c2,...,cn,面值可能相同,請問如何選取硬幣,可以使得在其原始位置不相鄰的條件下。所選幣值總和最大
2.思路
c[i]為第i個硬幣的面值,定義一個d[i],代表從開始位置到第i個硬幣當(dāng)前最大的幣值總和,那么對于第i個位置的硬幣,根據(jù)不相鄰的選擇,只有兩種選擇,一種是選取它,則轉(zhuǎn)變?yōu)榍笏癷-2位置的幣值最大和問題,d[i]=d[i-2]+c[i],另外一種是不選取它,則轉(zhuǎn)變?yōu)榍笏癷-1位置的幣值最大和問題,相應(yīng)的d[i]=d[i-1],則狀態(tài)轉(zhuǎn)移方程為:
d[i]=max{d[i-2]+c[i],d[i-1]}
3.代碼
public class Main {public static int way(int c[],int n,int d[]){if (n<2) //長度小于2的話,直接返回結(jié)果return d[n];d[0]=0;//第0個位置為0d[1]=c[1]; //第一個位置就為第一個位置硬幣的面值for (int i = 2; i <=n ; i++) {d[i]=Math.max(d[i-2]+c[i],d[i-1]); //狀態(tài)轉(zhuǎn)移方程System.out.println("當(dāng)前位置為"+i+"的最大硬幣和為:"+d[i]);}return d[n];}public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int c[]=new int[n+1];int d[]=new int[n+1];for (int i = 1; i <= n; i++) {c[i]=sc.nextInt();}int max_sum=way(c,n,d);System.out.println(max_sum);} }4.結(jié)果
總結(jié)
以上是生活随笔為你收集整理的动态规划——硬币找零和币值最大化问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求二叉树最长路径长度和
- 下一篇: 求1~n的全排列组合