zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    bzoj 3924
    bzoj 1095
    luogu 4886
    bzoj 2152
    CF960G
    bzoj 3561
    bzoj 4176
    bzoj 4407
    bzoj 3309
    luogu 4608
  • 原文地址:https://www.cnblogs.com/yzcstc/p/2977694.html
Copyright © 2011-2022 走看看