• poj3040


    一、题意:约翰要给他的牛贝西发工资,每天不得低于C元,约翰有n种面值的钱币,第i种的面值为v_i,数量有b_i。问这些钱最多给贝西发多少天的工资。注意,每种面值的金钱都是下一种的面值的倍数。

    二、思路:分三步解决:1. 按照面值从大到小取,面值大于等于C的,直接取光。2. 再按面值从大到小取,凑近C,可以小于等于C,但不能大于C.3.最后从小到大取,凑满C,这里的凑满可以等于大于C。然后将上述2,3步取到的面值全部取走,再转入步骤2,这样每次找到的取法就是当前最优取法,直到所剩下的金币总价值不够C结束。

    三、代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <set>
     5 #include <queue>
     6 #include <algorithm>
     7 #define MAXN 11111
     8 #define MAXM 222222
     9 #define INF 1000000000
    10 using namespace std;
    11 int n, c;
    12 typedef pair<int, int> P;
    13 P a[22];
    14 int use[22], sum[22];
    15 int main()
    16 {
    17     scanf("%d%d", &n, &c);
    18     for(int i = 0; i < n; i++) scanf("%d%d", &a[i].first, &a[i].second);
    19     sort(a, a + n);
    20     int ans = 0;
    21     for(int i = n - 1; i >= 0; i--)
    22         if(a[i].first >= c)
    23         {
    24             ans += a[i].second;
    25             a[i].second = 0;
    26         }
    27     while(true)
    28     {
    29         int flag = 0;
    30         int tmp = c;
    31  
    32         memset(use, 0, sizeof(use));
    33         for(int i = n - 1; i >= 0; i--)
    34             if(a[i].second)
    35             {
    36                 int k = tmp / a[i].first;
    37                 int mi = min(a[i].second, k);
    38                 tmp -= mi * a[i].first;
    39                 use[i] = mi;
    40                 if(tmp <= 0)
    41                 {
    42                     flag = 1;
    43                     break;
    44                 }
    45             }
    46         if(tmp > 0)
    47         {
    48             for(int i = 0; i < n; i++)
    49                 if(a[i].second > use[i])
    50                 {
    51                     while(use[i] < a[i].second)
    52                     {
    53                         tmp -= a[i].first;
    54                         use[i]++;
    55                         if(tmp <= 0)
    56                         {
    57                             flag = 1;
    58                             break;
    59                         }
    60                     }
    61                     if(tmp <= 0) break;
    62                 }
    63         }
    64         if(!flag) break;
    65         int mx = INF;
    66         for(int i = n - 1; i >= 0; i--)
    67         if(use[i]) mx = min(mx, a[i].second / use[i]);
    68         ans += mx;
    69         for(int i = n - 1; i >= 0; i--)
    70             if(use[i]) a[i].second -= mx * use[i];
    71  
    72     }
    73     printf("%d
    ", ans);
    74     return 0;
    75 }
    View Code

      

  • 相关阅读:
    处理缺失值
    数据清理
    数据聚合
    ajax动态生成table
    MangeEmpHashMap
    Arraylist的雇员管理操作
    jsp获取一个对象和list对象
    Controller比较两个对象discs、outlets中的元素是否相等。相同则相应的checkbox为checked
    限制input text输入的类型(数字,字母,小数点)
    联合主键的映射运用
  • 原文地址:https://www.cnblogs.com/acm-jing/p/9833190.html
Copyright © 2020-2023  润新知