BZOJ 1685 [Usaco2005 Oct]Allowance 津贴:贪心【给硬币问题】

题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=1333

题意:

  有n种不同币值的硬币,并保证大币值一定是小币值的倍数。

  每种硬币的币值为val,数量为cnt。

  每个月你要给Bessie发金额为c的津贴(可以比c多,但不能少)。

  问你最多能发多少个月。

 

题解:

  贪心。

 

  贪心策略:

    (1)如果能恰好凑出c的钱,则应尽可能使用大币值的硬币。

    (2)如果不能恰好凑出,则应让花的冤枉钱尽可能少。

 

  实现:

    先按币值从大到小排序。。。

    (1)在保证不花冤枉钱的前提下,尽可能使用大硬币。

    (2)如果没凑够c,则再付一个币值最小的硬币。(在第一步之后,再任意给出一个硬币都会使总付出大于c)

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define MAX_N 25
 6 
 7 using namespace std;
 8 
 9 struct Coin
10 {
11     int val;
12     int cnt;
13     Coin(int _val,int _cnt)
14     {
15         val=_val;
16         cnt=_cnt;
17     }
18     Coin(){}
19     friend bool operator < (const Coin &a,const Coin &b)
20     {
21         return a.val>b.val;
22     }
23 };
24 
25 int n,c;
26 int ans=0;
27 Coin coin[MAX_N];
28 
29 bool pay()
30 {
31     int rest=c;
32     for(int i=0;i<n;i++)
33     {
34         int temp=min(coin[i].cnt,rest/coin[i].val);
35         coin[i].cnt-=temp;
36         rest-=temp*coin[i].val;
37     }
38     if(rest==0) return true;
39     for(int i=n-1;i>=0;i--)
40     {
41         if(coin[i].cnt!=0)
42         {
43             coin[i].cnt--;
44             return true;
45         }
46     }
47     return false;
48 }
49 
50 int main()
51 {
52     cin>>n>>c;
53     for(int i=0;i<n;i++)
54     {
55         cin>>coin[i].val>>coin[i].cnt;
56     }
57     sort(coin,coin+n);
58     while(pay()) ans++;
59     cout<<ans<<endl;
60 }

 

posted @ 2017-09-20 21:38  Leohh  阅读(227)  评论(0编辑  收藏  举报