【贪心算法】POJ-3040 局部最优到全局最优
一、题目
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.
OutputLine 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.
二、思路&心得
贪心题目:从局部最优解得到全局最优解。
贪心策略如下:先对数据按照金额从小到大进行排序。对于金额大于C的纸币,直接全部取出;之后进行若干次循环,每次循环中先从大到小尽可能取到小于C的最大金额,之后再从小到大尽可能凑满C,允许超出一个当前最小金额值,一次处理结束后更新相应金额的数量。
这个贪心策略的数学化证明暂时没有想到,题目中还给出“金额之间还有确定的倍数关系”,也不清楚这个信息在算法中具体体现了什么作用。对于这个贪心策略,一个较为直观的解释如下:类比生活中买东西,当消费了一定金额后,我们肯定都是使用尽可能多的大面值的RMB,再使用小面值的,整个题目的思想应该跟这个差不多,我们生活中都下意识使用了很多的贪心策略。
PS:做这个题目时,实在被坑了好久,花了三四个小时,RE + WA无数次才过,主要的问题还是自己一开始上手时,所使用的贪心策略完全错误,尝试了多种,并且举反例证明之后才逐渐找到了正确的贪心策略。
三、代码
#include<cstdio>
#include<climits>
#include<algorithm>
using namespace std;
const int MAX_N = 25;
int N, C;
int ans;
int use[MAX_N];
struct Money {
int value;
int number;
} a[MAX_N];
bool cmp(Money a, Money b) {
return a.value < b.value;
}
void solve() {
int i, start = -1;
int min_num, dist;
//计算所有面额大于C的数据
for (i = N - 1; i >= 0; i --) {
if (a[i].value >= C) {
ans += a[i].number;
} else {
start = i;
break;
}
}
while (1) {
fill(use, use + N, 0);
dist = C;
//从大到小取到小于C的最大数值
for (i = start; i >= 0; i --) {
if (a[i].number) {
min_num = min(dist / a[i].value, a[i].number);
use[i] = min_num;
dist -= a[i].value * min_num;
}
}
//从小到大凑满C
if (dist > 0) {
for (int i = 0; i <= start; i ++) {
if (a[i].number) {
min_num = min((dist + a[i].value - 1) / a[i].value, a[i].number - use[i]);
use[i] += min_num;
dist -= a[i].value * min_num;
if (dist <= 0) break;
}
}
}
if (dist > 0) break;
//数量更新
min_num = INT_MAX;
for (i = 0; i <= start; i ++) {
if (use[i])
min_num = min(min_num, a[i].number / use[i]);
}
for (i = 0; i <= start; i ++) {
if (use[i]) {
a[i].number -= min_num * use[i];
}
}
ans += min_num;
}
printf("%d\n", ans);
}
int main() {
while (~scanf("%d %d", &N, &C)) {
ans = 0;
for (int i = 0; i < N; i ++) {
scanf("%d %d", &a[i].value, &a[i].number);
}
sort(a, a + N, cmp);
solve();
}
return 0;
}
【贪心算法】POJ-3040 局部最优到全局最优的更多相关文章
- [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)
一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...
- 个人总结-----非贪心算法的图的m着色判断及优化问题
1.问题描述: 对于著名的图的m着色,有两个主要的问题,一个是图的m色判定问题,一个是图的m色优化问题,描述如下. 图的m色判定问题: 给定无向连通图G和m种颜色.用这些颜色为图G的各顶点着色.问是否 ...
- 「面试高频」二叉搜索树&双指针&贪心 算法题指北
本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...
- 『嗨威说』算法设计与分析 - 贪心算法思想小结(HDU 2088 Box of Bricks)
本文索引目录: 一.贪心算法的基本思想以及个人理解 二.汽车加油问题的贪心选择性质 三.一道贪心算法题点拨升华贪心思想 四.结对编程情况 一.贪心算法的基本思想以及个人理解: 1.1 基本概念: 首先 ...
- POJ 3040 Allowance【贪心】
POJ 3040 题意: 给奶牛发工资,每周至少 C 元.约翰手头上有面值V_i的硬币B_i个,这些硬币的最小公约数为硬币的最小面值.求最多能发几周? 分析: 贪心策略是使多发的面额最小(最优解).分 ...
- poj 1088 滑雪(贪心算法)
思想: (贪心算法 ,看到题目是中文才做的) 先对数组中的数据进行排序,从最小的数据计算 当前的顶点的可以滑行的最大值=max(周围可达的顶点的可以滑行的最大值)+1 这样计算最后产生的路径肯定是最大 ...
- POJ 2287 田忌赛马 贪心算法
田忌赛马,大致题意是田忌和国王赛马,赢一局得200元,输一局输掉200元,平局则财产不动. 先输入一个整数N,接下来一行是田忌的N匹马,下一行是国王的N匹马.当N为0时结束. 此题为贪心算法解答,有两 ...
- 贪心算法(Greedy Algorithm)
参考: 五大常用算法之三:贪心算法 算法系列:贪心算法 贪心算法详解 从零开始学贪心算法 一.基本概念: 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以 ...
- LEETCODE —— Best Time to Buy and Sell Stock II [贪心算法]
Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...
随机推荐
- jQuery的一点小结
1.jQuery常用选择器 筛选: $('div').has('p'); // 选择包含p元素的div元素 $('div').not('.myClass'); //选择class不等于myClass的 ...
- vue中使用codemirror
https://blog.csdn.net/oumaharuki/article/details/79268498 别人的记载,写的很不错,还有下载的方法 以下是自己使用过的,做出来的例子: 做出来 ...
- CodeIgniter Doctrine2基本使用(一)(转)
CodeIgniter Doctrine2基本使用(一) 之前写了一篇文章叫作<CodeIgniter 3.0整合Doctrine2>里面介绍了一些简单的Doctrine2的用法,当然我也 ...
- Installation failed: Timeout was reached: Operation timed out after 10000 milliseconds with 0 out of 0 bytes received
Trying this option worked for me. library(httr) with_config(use_proxy(...), install_github(...)) OR ...
- Noip前的大抱佛脚----数论
目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...
- re 模块错误 error: bad character range
下午,看到堆栈的内容.于是上机实验了一番 >>> bds = '10+6/5-4*2' # 数学运算表达式 想用 findall 把运算符号提取出来 >>> imp ...
- 2_C语言中的数据类型 (九)逻辑运算符与if语句、switch、条件运算符?、goto语句与标号
1 条件分支语句 1.1 关系运算符 在C语言中0代表false,非0代表真 1.1.1 < 小于 1.1.2 <= 小于 ...
- vmware虚拟机中的系统(例如kali),输入内容有延迟和卡顿的解决方案
实际上是因为内存在vmware里设置小了,设置得大点即可, 比如我的kali之前是2gb,然后之前倒是没出过这种问题,但是这次更新系统后可能出了一些问题就变得卡了, 所以我就把kali的内存从2gb调 ...
- vmware打开vmx文件不能创建虚拟机的问题
这种情况一般结束 vmware-tray 进程,然后直接在文件管理器里打开vmx文件即可创建(打开方式为vmware), 直接在vmware里打开虚拟机文件可能会出现无反应(不创建虚拟机)的情况.
- mysql mtr写入数据
BEGIN; --disable_query_log --let $rows= 100 WHILE($rows) { --eval INSERT INTO t1 (a) VALUES ( $rows ...