poj3040( Allowance,贪心)

Allowance

Time Limit: 1000MS


Memory Limit: 65536K

Total Submissions: 2300


Accepted: 945

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 6
10 1
1 100
5 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.


题解:

 1. 按照面值从大到小取,面值大于等于C的,直接取光。

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

AC:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

struct node{
  int x,y;
}a[1024];

bool cmp(node a,node b)
{
    return a.x>b.x;
}

int main()
{
  int n,c,sum,need[1024],l,s;
  while(scanf("%d%d",&n,&c)!=EOF)
  {
      l=-1,sum=0;
      for(int i=0;i<n;i++)
          scanf("%d%d",&a[i].x,&a[i].y);
      sort(a,a+n,cmp);                  ///先排序
      for(int i=0;i<n&&a[i].x>=c;i++)   ///如果可以直接用,就直接用,累加所以可以直接用的
          sum+=a[i].y,a[i].y=0,l=i;
      while(1)
      {
          memset(need,0,sizeof(need));
          s=c;
          for(int i=l+1;i<n;i++)         
          {
              if(a[i].x<=s&&a[i].y)     ///先从大到小累加,累加和不可以大于c
              {
                  need[i]=min(a[i].y,s/a[i].x);  ///计算一次一次需要多少i号个硬币
                  s-=a[i].x*need[i];
              }
          }
          if(s>0)
          {
              for(int i=n-1;i>l;i--)    ///从小到大,取一个加上后大于等于c的
              {
                if(a[i].x>=s&&a[i].y&&a[i].y>need[i])
                {
                 s-=a[i].x;
                 need[i]++;
                 break;
                }
              }
          }
          if(s>0) break;
          int mins=999999999;
          for(int i=0;i<n;i++)
              if(need[i])
                mins=min(mins,a[i].y/need[i]);///计算按这种比例可以一次发多少个星期
          sum+=mins;
          for(int i=0;i<n;i++)
              a[i].y-=need[i]*mins;           ///将发出去的硬币去掉
      }
      printf("%d\n",sum);
  }
  return 0;
}

转载于:https://www.cnblogs.com/wangtao971115/p/10358371.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值