動態規划-最少硬幣問題


問題描述:設有n種不同面值的硬幣,各硬幣的面值存在於數組T[1:n]中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數存於數組Coins[1:n]中。對任意錢數0≤m≤20001,設計一個最少硬幣找錢m的方法。

算法設計:對於給定的1≤n≤10 ,硬幣面值數組T和可以使用的各種面值的硬幣數組Coins,以及錢數m, 0≤m≤20001,計算找錢m的最少硬幣數。

數據輸入:由文件input. Txt提供輸入數據,文件的第1行中只有一個整數給出n的值,第2行起每行兩個數,分別是T[j]和Coins[j]。最后一行是要找的錢數m。

結果輸出:將計算出的最少硬幣數輸出到文件output.txt。問題無解時輸出-1。

 

輸入文件示例input.txt:

3

1 3

2 3

5 3

18

輸出文件示例output.txt:

5

 

關注點:

1.多重背包 (每個物品有固定次數上限)

2.求的是最少

3.背包不能有空

 

代碼:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int maxint=2147483647;  4 void getit(int* t,int* coin,int ncoin,int money,int **m)  5 {  6     m[ncoin][0]=0;  7     for(int i=1;i<=money;i++)  8  {  9         m[ncoin][i]=maxint; 10         for(int j=1;j<=coin[ncoin];j++) 11           if(i==t[ncoin]*j) 12  { 13               m[ncoin][i]=j; 14               break; 15  } 16  } 17       
18     for(int i=ncoin-1;i>=0;i--) 19  {
       //復制一遍
20 for(int j=0;j<=money;j++) 21 m[i][j]=m[i+1][j]; 22 //修改到最佳 23 for(int j=money;j>=t[i];j--)//從后往前做
       /*好處:不用考慮前面已經用了該面值的硬幣多少個。m數組記錄的不是單一面值硬幣用到的個數,而是所有面值硬幣用到的總個數
        壞處:循環次數多了*/
24 for(int k=1;k<=coin[i];k++) 25 if((j-t[i]*k>=0)&&(m[i][j-t[i]*k]!=maxint)&&(m[i][j-t[i]*k]+k<m[i][j])) 26 m[i][j]=m[i][j-t[i]*k]+k; 27 } 28 if(m[0][money]==maxint)printf("-1"); 29 else printf("%d\n",m[0][money]); 30 31 } 32 33 int main() 34 { 35

    //輸入
    int ncoin; 36 scanf("%d",&ncoin); 37 int* t=(int *)malloc(sizeof(int)*ncoin); 38 int* coin=(int *)malloc(sizeof(int)*ncoin); 39 for(int i=0;i<ncoin;i++) 40 scanf("%d %d",&t[i],&coin[i]); 41 int money; 42 scanf("%d",&money);
    //准備
43 int** m=(int **)malloc(sizeof(int *)*ncoin); 44 for(int i=0;i<ncoin;i++) 45 m[i]=(int *)malloc(sizeof(int)*(money+1)); 46 int** num=(int **)malloc(sizeof(int *)*ncoin); 47 for(int i=0;i<ncoin;i++) 48 num[i]=(int *)malloc(sizeof(int)*(money+1));
    //執行
49 getit(t,coin,ncoin-1,money,m);
    //打印過程
50 for(int i=0;i<ncoin;i++) 51 { 52 for(int j=0;j<=money;j++) 53 printf("%d ",m[i][j]); 54 printf("\n"); 55 } 56 return 0; 57 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM