poj1276

题意:给你一堆钱,有许多面值,每种若干张,请找出利用这些钱可以凑成的最接近且小于给定的数字的数额。。

思路:多重背包。。。

 1 /*
 2   State:Accepted
 3   Time:2013.3.3
 4 */
 5 #include <iostream>
 6 #include <cstring>
 7 #include <string>
 8 #include <cstdlib>
 9 #include <cstdio>
10 #include <cmath>
11 #include <algorithm>
12 #include <vector>
13 #define CLR(NAME) memset(NAME , 0 , sizeof(NAME))
14 
15 const int maxm = 100010;
16 int  f[maxm] , fnum[maxm] , num[150] , d[150] , m ,n; 
17 
18 void dp(){
19       CLR(f);
20       scanf("%d",&n);
21       for (int i = 1; i <= n ; ++i)
22           scanf("%d%d",&num[i] , &d[i]);      
23       if  (n == 0 || m == 0){
24           printf("0\n");
25           return;
26       }
27       
28       f[0] = 1;
29       for (int i = 1; i <= n; ++i){
30           memset(fnum , 1000000 , sizeof(fnum) );
31           for (int j = m; j >= 0; --j)
32             if (f[j]){
33                for (int k = 0;  j + d[i] * k <= m && k <= num[i] ; ++k)
34                   if (f[j + d[i] * k] && k >= fnum[j + d[i] *k]) break;
35                   else {
36                          f[j + d[i] * k] = 1;
37                          fnum[j + d[i] *k] = k;
38                   }
39                 }
40          }
41       for (int i = m ; i >= 0; --i)
42         if  (f[i]) {  printf("%d\n", i);   return; }
43 }
44 
45 int main(){
46      freopen("poj1276.in","r",stdin);
47      freopen("poj1276.out","w",stdout);
48      while (scanf("%d",&m)!= EOF){
49         dp();
50      }
51 }

 

posted on 2013-03-23 20:50  yzcstc  阅读(167)  评论(0编辑  收藏  举报