POJ-1276 Cash Machine---多重背包
题目链接:
https://cn.vjudge.net/problem/POJ-1276
题目大意:
有各种不同面值的货币,每种面值的货币有不同的数量,请找出利用这些货币可以凑成的最接近且小于等于给定的数字cash的金额。
解题思路:
多重背包+二进制优化
dp[i]为真表示可以凑出i元
注意dp[0] = true
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 const int maxn = 1e6 + 10; 7 bool dp[maxn]; 8 int n, m; 9 void Zeroone(int cost) 10 { 11 for(int i = m; i >= cost; i--) 12 if(dp[i - cost])dp[i] = 1; 13 } 14 void Compete(int cost) 15 { 16 for(int i = cost; i <= m; i++) 17 if(dp[i - cost])dp[i] = 1; 18 } 19 void solve(int cost, int amount) 20 { 21 if(cost * amount >= m) 22 Compete(cost); 23 else 24 { 25 int k = 1;//二进制优化 26 while(k <= amount) 27 { 28 Zeroone(k * cost); 29 amount -= k; 30 k *= 2; 31 } 32 Zeroone(amount * cost); 33 } 34 } 35 int main() 36 { 37 while(scanf("%d%d", &m, &n) != EOF) 38 { 39 int amount, cost; 40 memset(dp, 0, sizeof(dp)); 41 dp[0] = 1; 42 while(n--) 43 { 44 scanf("%d%d", &amount, &cost); 45 solve(cost, amount); 46 } 47 for(int i = m; i >= 0; i--) 48 if(dp[i]) 49 { 50 printf("%d\n", i); 51 break; 52 } 53 } 54 return 0; 55 }
越努力,越幸运