題目在 http://poj.org/problem?id=1276
題目大意是說,我現在要從ATM中取錢,M
ATM裡面有若干種貨幣,每一種都有對應的貨幣面額和張數。
問現在ATM能夠取出來的 小於等於M的最大金額。
若將M理解為背包重量,而每種貨幣的面額理解成 value,貨幣的面額同樣理解成重量,那麼這個問題就是一個多重背包問題。
多重背包問題可以轉換成完全背包,使用一個used資料,used[k]的含義是:對於每一中貨幣 i, 達到金額 k 的時候,所使用的 面額是 i 的貨幣的個數。
對於迴圈體內的每個金額,我們要求達到這個金額所使用的貨幣數目要 小於等於給定的 這種貨幣的數量。
代碼如下:
Source CodeProblem: 1276User: hopeztmMemory: 948KTime: 16MSLanguage: C++Result: AcceptedSource Code#include <stdio.h>#include <memory.h>#define MAX_CASH 100001struct Cash{int amount;int demo;};int dp[MAX_CASH];int used[MAX_CASH];Cash allCash[11];int nCash;int nDeliver;int maxCash(){if(nCash == 0 || nDeliver == 0)return 0;int i,j,k;memset(dp, 0, sizeof(dp));for( i = 1; i <= nCash; i++){memset(used, 0, sizeof(used)); //使用used 資料來標記 used[j] 達到金額 j 的時候,所使用的 第 i 中鈔票的個數for( j = allCash[i].demo ; j <= nDeliver; j++){if((dp[j] < dp[j - allCash[i].demo] + allCash[i].demo)&& used[j - allCash[i].demo] + 1 <= allCash[i].amount) //要求到 金額j 的時候,所使用的 i 鈔票個數小於等於給定的數目{dp[j] = dp[j - allCash[i].demo] + allCash[i].demo;used[j] = used[j - allCash[i].demo] + 1;} }}return dp[nDeliver];}int main(){while(scanf("%d", &nDeliver) != EOF){scanf("%d", &nCash);for( int i = 1; i <= nCash; i++){scanf("%d%d", &allCash[i].amount, &allCash[i].demo);}printf("%d\n", maxCash());}return 0;}