poj3040

来源:互联网 发布:不求上进的玉子 知乎 编辑:程序博客网 时间:2024/04/29 03:24


Allowance
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 2819 Accepted: 1134

Description

As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.

Input

* Line 1: Two space-separated integers: N and C 

* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.

Output

* Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowance

Sample Input

3 610 11 1005 120

Sample Output

111

Hint

INPUT DETAILS: 
FJ would like to pay Bessie 6 cents per week. He has 100 1-cent coins,120 5-cent coins, and 1 10-cent coin. 

OUTPUT DETAILS: 
FJ can overpay Bessie with the one 10-cent coin for 1 week, then pay Bessie two 5-cent coins for 10 weeks and then pay Bessie one 1-cent coin and one 5-cent coin for 100 weeks.




题意:n种面额的钱币,用于付费,每周至少付c个单位的钱。问可以最多付多少周。

那对于面额大于等于c的肯定就是一个钱币一个周。

小于的,先取大的,因为大的是小的的倍数,小的留着可以跟大的拼出一个周的费用,小的提前用了以后每周会多付很多钱,所以先取大的。

如果取到哪一个加一个进去都会超出费用c,那么取一个赔得最少的(超出c最少)数值是最优的策略。

从面额最小开始取,如果有就可以取。


如果以上两步循环步骤结束,c还是没有被填满,说明全部钱都不足以支付一周的费用,不再找了退出。

每周的支付情况是由固定个种类个数的钱币组成,只能取最小的倍数个才能保证取得了,

比如种类0 1 2有5 4 4个,方案每种1 2 2 个可以凑齐一周的费用,min(5/1,4/2,4/2) = 2,所以这种组合足够支付两周。这样做是为了防止超时。


#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>const int N = 10010;typedef long long ll;using namespace std;typedef long long ll;int mod = 1000000007;struct Node{  int v, w;  bool operator < (const Node &b)const  {    return v > b.v;  }  void input()  {    scanf("%d%d", &v, &w);  }}rec[21];int main(){   int n ,c;   while (~scanf("%d%d", &n, &c))   {      ll ans = 0;      for (int i = 0; i < n; i++)        rec[i].input();      sort(rec, rec + n);      for (int i = 0; i < n; i++)       if (rec[i].v >= c)        {          ans += rec[i].w;          rec[i].w = 0;          continue;        }      while (1)      {        int all = c;        int hash[22] = {0};        for (int i = 0; i < n; i++)        {          int use = 0;          if (rec[i].w == 0)            continue;          use = min(rec[i].w, all / rec[i].v);          if (all)          {            all -= rec[i].v * use;            hash[i] += use;          }else            break;        }        for (int i = n - 1; i >= 0; i--)        {          if (rec[i].w - hash[i] > 0 && all)          {            hash[i]++;            all = 0;            break;          }        }        if (all)          break;        int minuse = 1<<20;        for (int i = 0; i < n; i++)        {                   if (hash[i])            minuse = min(minuse, rec[i].w / hash[i]);        }        for (int i = 0; i < n; i++)          rec[i].w -= minuse * hash[i];        ans += minuse;      }      printf("%lld\n", ans);   }    return 0;}




0 0
原创粉丝点击