poj 1276 Cash Machine
题意:
一个银行有若干不同面值的货币,每个面值有不同的数量,求银行可以凑出最大的小于等于给定金额的钱的数值。
思路:
组合背包裸题,把数量以二进制拆分,就可以凑出从1到k的所有数,时间复杂度降到log(k)。之后再用0,1背包解决。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <vector> 5 using namespace std; 6 7 const int M = 100005; 8 9 int f[M]; 10 11 vector<int> num,val; 12 13 int main() 14 { 15 int cash,n; 16 17 while (scanf("%d%d",&cash,&n) != EOF) 18 { 19 memset(f,0,sizeof(f)); 20 21 num.clear(); 22 val.clear(); 23 24 for (int i = 0;i < n;i++) 25 { 26 int t,d; 27 28 scanf("%d%d",&t,&d); 29 30 int cnt = 0; 31 32 while (1) 33 { 34 int tmp = (1 << cnt); 35 36 if (t <= tmp) 37 { 38 num.push_back(t); 39 val.push_back(t * d); 40 break; 41 } 42 43 num.push_back(tmp); 44 val.push_back(tmp * d); 45 46 t -= tmp; 47 48 cnt++; 49 } 50 } 51 52 int ans = 0; 53 54 for (int i = 0;i < val.size();i++) 55 { 56 for (int j = cash;j >= val[i];j--) 57 { 58 f[j] = max(f[j],f[j-val[i]] + val[i]); 59 ans = max(ans,f[j]); 60 } 61 } 62 63 printf("%d\n",ans); 64 } 65 66 return 0; 67 }
康复训练中~欢迎交流!