1. 程式人生 > >最少硬幣找零問題-動態規劃

最少硬幣找零問題-動態規劃

動態規劃把問題分為子為題,解決了這些子問題,再把子問題合併起來,便可以得到問題的解。在解決子問題過程中,需要把子問題的解儲存起來方便後面使用。

最少硬幣找零問題為:給予不同面值的硬幣若干種種(每種硬幣個數無限多),用若干種硬幣組合為某種面額的錢,使硬幣的的個數最少。

在現實生活中,我們往往使用的是貪心演算法,比如找零時需要13元,我們先找10元,再找2元,再找1元。這是因為現實生活中的硬幣(紙幣)種類特殊。如果我們的零錢可用的有1、2、5、9、10。我們找零18元時,貪心演算法的策略是:10+5+2+1,四種,但是明明可以用兩個9元的啊。

所以可以使用動態規劃,找零18元時,我們首先找18-1=17,18-2=15,18-5,=13,18-9,=9,18-10=8;再找17-1……。這樣遞迴解決子問題

  1. #include<iostream>
  2. usingnamespace std;  
  3. //money需要找零的錢
  4. //coin可用的硬幣
  5. //硬幣種類
  6. void FindMin(int money,int *coin, int n)  
  7. {  
  8.     int *coinNum=newint[money+1]();//儲存1...money找零最少需要的硬幣的個數
  9.     int *coinValue=newint[money+1]();//最後加入的硬幣,方便後面輸出是哪幾個硬幣
  10.     coinNum[0]=0;  
  11.     for(int i=1;i<=money;i++)  
  12.     {  
  13.         int minNum=i;//i面值錢,需要最少硬幣個數
  14.         int usedMoney=0;//這次找零,在原來的基礎上需要的硬幣
  15.         for(int j=0;j<n;j++)  
  16.         {  
  17.             if(i>=coin[j])//找零的錢大於這個硬幣的面值
  18.             {  
  19.                 //if(coinNum[i-coin[j]]+1<=minNum)//所需硬幣個數減少了
  20.                 /* 
  21.                 上面的判斷語句有問題,在更新時,需要判斷i-coin[j]是否能找的開,如果找不開,就不需要更新。
     
  22.                 多謝zywscq 指正 
  23.                 */
  24.                 if(coinNum[i-coin[j]]+1<=minNum&&(i==coin[j]||coinValue[i-coin[j]]!=0))//所需硬幣個數減少了
  25.                 {  
  26.                     minNum=coinNum[i-coin[j]]+1;//更新
  27.                     usedMoney=coin[j];//更新
  28.                 }  
  29.             }  
  30.         }  
  31.         coinNum[i]=minNum;  
  32.         coinValue[i]=usedMoney;  
  33.     }  
  34.     //輸出結果
  35.     if(coinValue[money]==0)  
  36.         cout<<"找不開零錢"<<endl;  
  37.     else
  38.     {  
  39.         cout<<"需要最少硬幣個數為:"<<coinNum[money]<<endl;  
  40.         cout<<"硬幣分別為:";  
  41.         while(money>0)  
  42.         {  
  43.             cout<<coinValue[money]<<",";  
  44.             money-=coinValue[money];  
  45.         }  
  46.     }  
  47.     delete []coinNum;  
  48.     delete []coinValue;  
  49. }  
  50. int main()  
  51. {  
  52.     int Money=18;  
  53.     int coin[]={1,2,5,9,10};  
  54.     FindMin(Money,coin,5);  
  55. }  

相關推薦

硬幣--動態規劃入門

假設有幾種硬幣,如1、3、5,並且數量無限。請找出能夠組成某個數目的找零所使用最少的硬幣數。  #include<iostream> #include<math.h> #define INF 9999999 using namespace std; int m

最少硬幣問題-動態規劃

動態規劃把問題分為子為題,解決了這些子問題,再把子問題合併起來,便可以得到問題的解。在解決子問題過程中,需要把子問題的解儲存起來方便後面使用。 最少硬幣找零問題為:給予不同面值的硬幣若干種種(每種硬幣個數無限多),用若干種硬幣組合為某種面額的錢,使硬幣的的個數最少。

動態規劃最少硬幣問題、01揹包問題、完全揹包問題

題目一:01揹包問題 一個揹包總容量為V,現在有N個物品,第i個 物品體積為weight[i],價值為value[i],現在往揹包裡面裝東西,怎麼裝能使揹包的內物品價值最大? 題目二:完全揹包問題 一個揹包總容量為V,現在有N個物品,第i個 物品體積為weight[i],價值為value[i],每

最少硬幣問題(動態規劃遞推式)

最少硬幣問題 時間限制(普通/Java) : 1000 MS/ 3000 MS          執行記憶體限制 : 65536 KByte總提交 : 247            測試

最少硬幣問題(動態規劃解決)

設有n中不同面值的硬幣,各硬幣的面值存在於陣列T[1..n]中,可以使用的面值硬幣個數不限。假如現在找的錢是j,1<<j<<L,求使得的硬幣數目最少 解決方法: 另c[i,j]代表用前中硬幣兌換j所用的最少數目。#include "stdafx.h"

動態規劃——硬幣

max 關系 i++ 是否 coin fine 個數 names std   動態規劃問題,主要在於需要想清楚遞推關系,num[i][j]表示能使用 i 種硬幣時,得到 j 零錢的最優解。   想來就是首先假設只能使用第一種硬幣 1 ,那麽會得到num[ 1 : n] =

動態規劃-硬幣問題四種情況

題目1:給定陣列arr,arr中所有的值都是正數且不重複。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定一個整數aim代表要找的錢數,求組成aim的最少貨幣數。 舉例:  arr[5,2,3],aim=20。  4張5元可以組成20元,其他的找錢方案都要使

硬幣問題(動態規劃

硬幣找零(動態規劃) 問題介紹 給定指定的硬幣種類,面值為 1, 3, 5(在此具體化些),給定所找零的錢數 sum,給出最少的硬幣找零數,每個種類的硬幣無限使用。 問題分析 看到這問題,當時我想到用貪心演算法來求解,最後求解方案因為巧合對了,後來在網上看到動態

斐波那契數列和階乘的尾函式優化,動態規劃解決最小硬幣和揹包問題

// 遞迴是一種解決問題的方法,它解決問題的各個小部分,直到解決最初的大問題。遞迴通常涉及函式呼叫自身 // 斐波那契數列尾呼叫優化 function fibonacci(n, acc1 = 1, acc2 = 1) { if (n === 1 || n === 2) { ret

硬幣,最長上升子序列,揹包問題等動態規劃問題詳解

1.硬幣找零 如果我們有面值為 1 元、3 元和 5 元的硬幣若干枚,如何用最少的硬幣湊夠 11 元? 首先我們思考一個問題,如何用最少的硬幣湊夠 i 元(i<11)?為什麼要這麼問呢? 兩個原因:1.當我們遇到一個大問題時,總是習慣把問題的規模變小,這樣便於分析討論。 2.這

硬幣問題(動態規劃求解)

如果我們有面值為1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠11元? (表面上這道題可以用貪心演算法,但貪心演算法無法保證可以求出解,比如1元換成2元的時候) 首先我們思考一個問題,如何用最少的硬幣湊夠i元(i<11)?為什麼要這麼問呢? 兩個原因:1.當

動態規劃求解硬幣問題——Java實現

動態規劃的基本思想是將待求解問題分解成若干個子問題,先求解子問題,並將這些子問題的解儲存起來,如果以後在求解較大子問題的時候需要用到這些子問題的解,就可以直接取出這些已經計算過的解而免去重複運算。儲存子問題的解可以使用填表方式,例如儲存在陣列中。  動態規劃的主要難點在於

硬幣動態規劃

#include "stdlib.h"#define N  63 void GetChange(int n,int j,int m[],int c[][N] )  { /*下標從1開始*/    int Max=10000;   int k,i,t;  int b[5]={0

詳解_動態規劃DAG_硬幣問題(完全揹包)

寫了好多結果一下卡住都沒了。。。(csdn怕是把大部分伺服器資源用在了廣告投放上吧) 參考數目:演算法競賽入門經典(第二版) NYOJ 995: 描述 在現實生活中,我們經常遇到硬幣找零的問題,例如,在發工資時,財務人員就需要計算最少的找零硬幣數,以便他們能從銀行拿回

動態規劃】之硬幣問題(難度:1星)

#include <stdio.h> /** * 原題: * 假設有幾種硬幣,如1塊、3塊、5塊,並且數量無限。 * 請找出能夠組成某個數目的找零所使用最少的硬幣數。 */ #def

硬幣問題:看分治/動態規劃/貪心演算法的區別與聯絡

硬幣找零問題:存在一堆面值為 v1、v2、v3 … 個單位的硬幣,問最少需要多少個硬幣才能找出總值為x單位的零錢?這裡我們假設v[]={0, 1, 2, 5, 10, 20, 50}。0是用來充位數的,這樣v1、v2與下標1、2對上。這裡v1必須為1,若不為1的話,給定一個

動態規劃演算法求解硬幣問題

硬幣找零問題描述:現存在一堆面值為 V1、V2、V3 … 個單位的硬幣,問最少需要多少個硬幣才能找出總值為 T 個單位的零錢?假設這一堆面值分別為 1、2、5、21、25 元,需要找出總值 T 為 63 元的零錢。 很明顯,只要拿出 3 個 21 元的硬幣就湊夠了 63

3233 硬幣(貪心+動態規劃

題目:Description小蛇是金融部部長。最近她決定製造一系列新的貨幣。假設她要製造的貨幣的面值為x1,x2,x3… 那麼x1必須為1,xb必須為xa的正整數倍(b>a)。例如1,5,125,

[LeetCode] Coin Change 2 硬幣之二

lee diff bit inf may tco nom not leet You are given coins of different denominations and a total amount of money. Write a function t

codevs 3961 硬幣【完全背包DP/記憶化搜索】

得到 可能 代碼 好的 default ++ -h 數值 rip 題目描述 Description 在現實生活中,我們經常遇到硬幣找零的問題,例如,在發工資時,財務人員就需要計算最少的找零硬幣數,以便他們能從銀行拿回最少的硬幣數,並保證能用這些硬幣發工資。