一、题目

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.

二、思路&心得

  • 贪心题目:从局部最优解得到全局最优解。

  • 贪心策略如下:先对数据按照金额从小到大进行排序。对于金额大于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 局部最优到全局最优的更多相关文章

  1. [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)

    一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...

  2. 个人总结-----非贪心算法的图的m着色判断及优化问题

    1.问题描述: 对于著名的图的m着色,有两个主要的问题,一个是图的m色判定问题,一个是图的m色优化问题,描述如下. 图的m色判定问题: 给定无向连通图G和m种颜色.用这些颜色为图G的各顶点着色.问是否 ...

  3. 「面试高频」二叉搜索树&双指针&贪心 算法题指北

    本文将覆盖 「字符串处理」 + 「动态规划」 方面的面试算法题,文中我将给出: 面试中的题目 解题的思路 特定问题的技巧和注意事项 考察的知识点及其概念 详细的代码和解析 开始之前,我们先看下会有哪些 ...

  4. 『嗨威说』算法设计与分析 - 贪心算法思想小结(HDU 2088 Box of Bricks)

    本文索引目录: 一.贪心算法的基本思想以及个人理解 二.汽车加油问题的贪心选择性质 三.一道贪心算法题点拨升华贪心思想 四.结对编程情况 一.贪心算法的基本思想以及个人理解: 1.1 基本概念: 首先 ...

  5. POJ 3040 Allowance【贪心】

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

  6. poj 1088 滑雪(贪心算法)

    思想: (贪心算法 ,看到题目是中文才做的) 先对数组中的数据进行排序,从最小的数据计算 当前的顶点的可以滑行的最大值=max(周围可达的顶点的可以滑行的最大值)+1 这样计算最后产生的路径肯定是最大 ...

  7. POJ 2287 田忌赛马 贪心算法

    田忌赛马,大致题意是田忌和国王赛马,赢一局得200元,输一局输掉200元,平局则财产不动. 先输入一个整数N,接下来一行是田忌的N匹马,下一行是国王的N匹马.当N为0时结束. 此题为贪心算法解答,有两 ...

  8. 贪心算法(Greedy Algorithm)

    参考: 五大常用算法之三:贪心算法 算法系列:贪心算法 贪心算法详解 从零开始学贪心算法 一.基本概念: 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以 ...

  9. 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 ...

随机推荐

  1. jQuery----jquery实现Tab键切换

    使用Jquery实现tab键切换,代码简洁易懂,实现逻辑清晰明了.具体总结如下: 需求分析: 鼠标进入tab切换模块,鼠标当前的模块上边框变为红色,并显示对应的商品名称.鼠标离开后,上边框恢复原色,图 ...

  2. 2017-2018-1 20155231 课堂测试 (ch06)

    2017-2018-1 20155231 课堂测试 (ch06) 1 (单选题|1分) 下面代码中,对数组x填充后,采用直接映射高速缓存,所有对x和y引用的命中率为(D) A .1 B .1/4 C ...

  3. 20145209刘一阳《JAVA程序设计》第三周课堂测试

    第三周课堂测试 1.使用汇编语言编写指令时,用一些简单的容易记忆的符号来代替二进制指令,比机器语言更为方便,属于高级语言.(B) A .true B .false 2.下列说法正确的是(ABCD) A ...

  4. RabbitMQ(四):RPC的实现

    原文:RabbitMQ(四):RPC的实现 一.RPC RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. ...

  5. lxml etree xpath

    from lxml import etree #####################基本用法: ##################### html = ''' <h1 class=&quo ...

  6. CodeForces 985D Sand Fortress

    Description You are going to the beach with the idea to build the greatest sand castle ever in your ...

  7. 一个本地DNS解析和mysql授权导致的Mysq连接失败问题(Access denied for user 'loan'@'kfcsdb1' (using password: YES))

    web:/home/web/ -u loan -p loan Enter password: ERROR 1045 (28000): Access denied for user 'loan'@'kf ...

  8. CS100.1x-lab1_word_count_student

    这是CS100.1x第一个提交的有意义的作业,自己一遍做下来对PySpark的基本应用应该是可以掌握的.相关ipynb文件见我github. 这次作业的目的如题目一样--word count,作业分成 ...

  9. 用 Python 破解 WIFI 密码,走到哪里都能连 WIFI

    WIFI 破解,Python 程序员必学技能.WIFI 已经完全普及,现在 Python 程序员没网,走到哪里都不怕! 教你们一招,如何在图片中提取 Python 脚本代码.图片发送至手机 QQ 长按 ...

  10. 解决在控制层springmvc框架发出的400状态的错误

    错误场景: 错误分析: 这也是我第一次遇到这个类型的异常,400响应状态代表:客户端发出的请求中携带的参数与服务器端接受的参数类型不匹配,进一步就是说我后台的实体类中数据类型为Date,而前台传递过来 ...