http://poj.org/problem?id=3040

FJ 有n种不同面值的硬币,每种硬币都有相应的个数,大面值的硬币值总能被小面值的硬币值整除,每周需要支付 Bessie   c元,问最多能支付Bessie多少周。

这题之所以能贪心,据说关键是这句话 where each denomination of coin evenly divides the next-larger denomination。

如果没有这个限制条件,有些情况是取不到最优解的。

把面值从小到大排序,然后从尾到头开始扫,能给多少就给多少,如果面值不够,就从头到尾扫,尽量取刚好超过数额的。

参考了别人代码,感觉写的很精妙。自己的水平还很欠缺。

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1000000000
#define N 100010
using namespace std; pair<int,int>p[];
int use[];
int main()
{
int n,c,sum;
scanf("%d%d",&n,&c);
sum=;
for(int i=;i<n;i++) scanf("%d%d",&p[i].first,&p[i].second);
sort(p,p+n);
for(int i=;i<n;i++) //从大面值 开始 如果面值 大于c 那么直接累加。
if(p[i].first>=c)
{
sum+=p[i].second;
p[i].second=;
}
while(true) //不断循环,直到不能在支付为止。
{
int tmp=c;
int flag=;
memset(use,,sizeof(use)); //记录每个面值的硬币使用了多少。
for(int i=n-;i>=;i--) //从大面值开始扫。
{ //注意这里只有一次循环,就把所有面值的使用情况扫出来了,因为如果不能用当前面值支付的话 k会变成0,并且要么会刚好支付完,要么tmp>0
if(p[i].second) //当前面值还有 不会出现浪费当前面值的情况
{
int k=tmp/p[i].first; //为了支付c元 当前面值最多可以用多少个,
int mi=min(k,p[i].second); //取最小值
tmp-=p[i].first*mi; //剩下 这么多
use[i]=mi; //记录使用数量
if(tmp<=) {flag=;break;} //tmp小于0 那么本次支付已结束
}
}
if(tmp>) //否则从小到大开始 给
{
for(int i=;i<n;i++)
{
if(p[i].second>use[i]) //如果没使用完
{
while(use[i]<p[i].second) //一直使用,因为当前用的面值是最小的那么这样也是最优的。
{
tmp-=p[i].first;
use[i]++;
if(tmp<=) {flag=;break;}
}
if(tmp<=&&flag==) break; //只有 flag==1的时候 tmp<=0
}
}
}
if(!flag) break; //已经不能完成支付
int mx=maxn;
for(int i=n-;i>=;i--) if(use[i]) mx=min(p[i].second/use[i],mx); //use[i]是一次支付时当前面值使用的情况,那么p[i].second/use[i] 就表示可以支付 这么多次,并且取的是所有当中的最小值。
sum+=mx;
for(int i=n-;i>=;i--) if(use[i]) p[i].second-=mx*use[i]; //取用了 mx次,所以相应数量减少这么多,这样会节省很多时间,不用每次重复计算,是一次很大的优化
}
printf("%d\n",sum);
return ;
}

poj-3040 Allowance (贪心)的更多相关文章

  1. POJ 3040 Allowance 贪心

    这题目的贪心思路还是有一点细节问题的. 还没有证明,据说是因为题目给的条件是每个价格是比它小的价格的倍数才能这么贪心的. 思路如下: 假设要给奶牛的钱为C 1)从大面值到小面值一次拿钱,能拿多少拿多少 ...

  2. POJ 3040 Allowance【贪心】

    POJ 3040 题意: 给奶牛发工资,每周至少 C 元.约翰手头上有面值V_i的硬币B_i个,这些硬币的最小公约数为硬币的最小面值.求最多能发几周? 分析: 贪心策略是使多发的面额最小(最优解).分 ...

  3. poj 3040 Allowance

    Allowance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1842   Accepted: 763 Descript ...

  4. 【贪心】Allowance POJ 3040

    题目链接:http://poj.org/problem?id=3040 题目大意:你有n种不同面值的硬币,面值为vi的有bi个."硬币的面额均匀地分配下一个更大的面额",即下一个更 ...

  5. 【POJ - 3040】Allowance(贪心)

    Allowance 原文是English,这里就放Chinese了 Descriptions: 作为创纪录的牛奶生产的奖励,农场主约翰决定开始给Bessie奶牛一个小的每周津贴.FJ有一套硬币N种(1 ...

  6. POJ 3040 贪心

    贪心好题 ---. 思路: 从大到小凑C 如果不够 再从小到大补满(超过)C //By SiriusRen #include <cstdio> #include <cstring&g ...

  7. Greedy:Allowance(POJ 3040)

    零用钱大作战 题目大意:农夫和牛又搞新花样了,现在农夫想给Bessie每个星期都给一点零用钱,农夫有一堆面值的钱币,并且这个钱币都能被上一个钱币整除(1,5,10,50),并且钱币有一定数量,要你求最 ...

  8. POJ 1456(贪心)

    #include <string.h> #include <iostream> #include <queue> #include <stdio.h> ...

  9. poj -3614 Sunscreen(贪心 + 优先队列)

    http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固 ...

随机推荐

  1. hdu 1043 Eight 经典八数码问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...

  2. 【BZOJ】【1016】【JSOI2008】最小生成树计数

    Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...

  3. [工作记录] Android OpenGL ES: non-square texture - continue

    previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...

  4. Win32 Plus Extra Height of Caption Bar

    you set the size of the non-client area by handling the WM_NCCALCSIZE message. But don't do this unl ...

  5. 在C#中调用VBScript和JavaScript等脚本的实现

    在C#中调用VBScript.JavaScript等脚本的实现 作者:郑佐 2004-04-26 以前在做工作流(workflow)项目的时候,里面有一项就是在用户制定流程定义时可以编写脚本来控制活动 ...

  6. UML 2.0(装载)

    在世界上统一建模语言UML2.0是完全不同的维度.它在本质上更加复杂和广泛. 与UML1.5版本相比,文件的程度也增加了. UML2.0中还增加了新的功能,所以它的使用可以更广泛. UML2.0将正式 ...

  7. 2014_GCJ_A

    题目链接:http://code.google.com/codejam/contest/2984486/dashboard#s=p0 最想吐槽的是想些DFS过小数据,居然写不出来,不知道我这半年的AC ...

  8. function的prototype

    prototype只有function才有的属性. var a = function() { this.age = 12; this.name = "haha"; }; a.pro ...

  9. 微信电脑版也能用公众号自定义菜单 微信1.2 for Windows发布

    昨日,微信电脑版发布更新,版本为微信1.2 for Windows,最大的特色就是加入了保存聊天记录功能,可以使用公账号菜单,手机上收藏的表情也能在电脑版上发送,可以接收转账消息. 本次微信pc版更新 ...

  10. Apache CXF实现Web Service(1)——不借助重量级Web容器和Spring实现一个纯的JAX-WS web service

    废话少说,先在Eclipse中新建一个Java Project (可以不是WTP的Dynamic Web Project) 选择Java Project 再看pom.xml 我们使用cxf 3.1.4 ...