POJ 3040 Allowance【贪心】
题意:
给奶牛发工资,每周至少 C 元。约翰手头上有面值V_i的硬币B_i个,这些硬币的最小公约数为硬币的最小面值。求最多能发几周?
分析:
贪心策略是使多发的面额最小(最优解)。分三个阶段:
1. 首先面额不小于C的硬币属于没办法节约的类型,先统统发掉。
2. 然后对硬币面额从大到小尽量凑得接近C,允许等于或不足C,但是不能超出C。
3. 接着按硬币面额从小到大凑满C(凑满的意思是允许超出一个最小面值,ps此处的最小面值指的是硬币剩余量不为0的那些硬币中的最小面值),凑满之后得出了最优解,发掉,进入步骤2.
这样就保证了每次都是当前的最优解,这个题很好地体现了贪心法的精髓。
从大到小排序,只要不超额就能放多少就放多少,最后再从小的开始找一个放进去能超额的。
正确性证明:
因为大的是小的倍数,所以大的放进去不超额一定要放进去,因为小的不管怎么取,再超过c之前一定会凑成这个大的面额,那么用大的代替一定更优。第一步做完之后,那么现在一定要再放进去一个硬币,那么选择最小的并且能大于c的也一定是最优的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=22;
int need[maxn];
struct node
{
int v,b;
bool operator <(const node & x) const
{
return v>x.v;
}
}coin[maxn]; int main()
{
int n,c;
while(scanf("%d %d",&n,&c)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d %d",&coin[i].v,&coin[i].b);
sort(coin+1,coin+1+n);
int ans=0;
while(1)
{
memset(need,0,sizeof(need));
int sum=c;
for(int i=1;i<=n;i++)
{
int tmp = sum/coin[i].v;
need[i]=min(tmp,coin[i].b);
sum-=need[i]*coin[i].v;
}
if(sum>0)
{
for(int i=n;i>=1;i--)
{
if(coin[i].b&&coin[i].v>=sum)// 从小到大找一个面值大于剩余sum的
{
need[i]++;
sum=0;
break;
}
}
}
if(sum>0)break;
int weeks=2e9;
for(int i=1;i<=n;i++)
{
if(need[i])
weeks=min(weeks,coin[i].b/need[i]);
}
for(int i=1;i<=n;i++)
if(need[i])
coin[i].b-=weeks*need[i];
ans+=weeks;
}
cout<<ans<<endl;
}
return 0;
}
POJ 3040 Allowance【贪心】的更多相关文章
- POJ 3040 Allowance 贪心
这题目的贪心思路还是有一点细节问题的. 还没有证明,据说是因为题目给的条件是每个价格是比它小的价格的倍数才能这么贪心的. 思路如下: 假设要给奶牛的钱为C 1)从大面值到小面值一次拿钱,能拿多少拿多少 ...
- poj 3040 Allowance
Allowance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1842 Accepted: 763 Descript ...
- 【贪心】Allowance POJ 3040
题目链接:http://poj.org/problem?id=3040 题目大意:你有n种不同面值的硬币,面值为vi的有bi个."硬币的面额均匀地分配下一个更大的面额",即下一个更 ...
- 【POJ - 3040】Allowance(贪心)
Allowance 原文是English,这里就放Chinese了 Descriptions: 作为创纪录的牛奶生产的奖励,农场主约翰决定开始给Bessie奶牛一个小的每周津贴.FJ有一套硬币N种(1 ...
- POJ 3040 贪心
贪心好题 ---. 思路: 从大到小凑C 如果不够 再从小到大补满(超过)C //By SiriusRen #include <cstdio> #include <cstring&g ...
- Greedy:Allowance(POJ 3040)
零用钱大作战 题目大意:农夫和牛又搞新花样了,现在农夫想给Bessie每个星期都给一点零用钱,农夫有一堆面值的钱币,并且这个钱币都能被上一个钱币整除(1,5,10,50),并且钱币有一定数量,要你求最 ...
- poj-3040 Allowance (贪心)
http://poj.org/problem?id=3040 FJ 有n种不同面值的硬币,每种硬币都有相应的个数,大面值的硬币值总能被小面值的硬币值整除,每周需要支付 Bessie c元,问最多能 ...
- POJ 1456(贪心)
#include <string.h> #include <iostream> #include <queue> #include <stdio.h> ...
- poj -3614 Sunscreen(贪心 + 优先队列)
http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固 ...
随机推荐
- Linux 命令详解(十一)Shell 解析 json命令jq详解
前言 在自动化部署中涉及到shell脚本需要动态读取很多配置文件,最好是json格式. 更多jq信息: http://stedolan.github.io/jq/manual/ 一.根据key获取va ...
- Mybatis 学习总结
1 Mybatis入门 1.1 单独使用jdbc编程问题总结 1.1.1 jdbc程序 public static void main(String[] args) { Connection conn ...
- ps知识集锦
1.工具箱 移动工具 [V]矩形.椭圆选框工具 [M]套索.多边形套索.磁性套索 [L]快速选择工具.魔棒工具 [W] 裁剪.透视裁剪.切片.切片选择工具 [C]吸管.颜色取样器.标尺.注释.12 ...
- html5 实时监听输入框值变化的完美方案:oninput & onpropertychange
结合 HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件来监听输入框值变化. H5手机端: <input type="text" ...
- 并行动画组QParallelAnimationGroup
QParallelAnimationGroup会同时执行添加到该组的所有动画 import sys from PyQt5.QtGui import QPixmap from PyQt5.QtCore ...
- Java SE之字符串常量池
Reference Document: 什么是字符串常量池? http://www.importnew.com/10756.html[Recommend] Java常量池理解与总结 http: ...
- POJ1258 Agri-Net【最小生成树】
题意: 有n个农场,已知这n个农场都互相相通,有一定的距离,现在每个农场需要装光纤,问怎么安装光纤能将所有农场都连通起来,并且要使光纤距离最小,输出安装光纤的总距离. 思路: 又是一个最小生成树,因为 ...
- Sql server 查询某个时间段,分布有几周,几月和几日
1. 查询:以“周”为单位 --查询以下时间段内分别有几周 --时间段:“2017-09-01”到“2017-10-1” select number as wknum from master..spt ...
- Database学习 - mysql 连接数据库 库操作
连接数据库 语法格式: mysql -h 服务器IP -P 端口号 -u用户名 -p密码 --prompt 命令提示符 --delimiter 指定分隔符 示例: mysql -h 127.0.0.1 ...
- shiro自定义realm支持MD5算法认证(六)
1.1 散列算法 通常需要对密码 进行散列,常用的有md5.sha, 对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文. 建议对md5进行散列时加salt(盐),进行 ...