一、题目

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. JavaSE日常笔记汇总

    1. If和switch的比较 2. continue的注意事项 在for循环中,当执行continue语句时,i++还是会执行,continue语句只代表此次循环结束,i还是会累加,并继续执行下次循 ...

  2. 系统重装后恢复Oracle数据库

    这周装系统的固态盘坏了,固态硬盘用到坏也是第一次碰到....只能新买个硬盘重装系统了.到了Oracle数据库恢复那一步了,其实很简单.只要没把数据库安装路径放在系统盘就行.*^____^* 先找到重装 ...

  3. day 85 Vue学习之vue-cli脚手架下载安装及配置

      1. 先下载node.js,下载地址:https://nodejs.org/en/download/ 找个目录保存,解压下载的文件,然后配置环境变量,将下面的路径配置到环境变量中. 由于 Node ...

  4. 为什么继续选择DELPHI?

    已经钻DELPHI很深了,当然现在DELPHI是过了最辉煌的时代.但为什么要继续下去,而不转向其它的?这是不是死脑筋? 我看了一下C#的LINQ的产生,然后又被实体框架所代替.思考了一下: 1)LIN ...

  5. member access within misaligned address 0x0000002c3931 for type 'struct ListNode‘

    From MWeb 在做leetcode 第2题时使用C语言编写链表时报错 错误复现 错误原因 解决办法 错误复现 报错时的代码如下 /** * Definition for singly-linke ...

  6. 大数据入门第八天——MapReduce详解(三)MR的shuffer、combiner与Yarn集群分析

    /mr的combiner /mr的排序 /mr的shuffle /mr与yarn /mr运行模式 /mr实现join /mr全局图 /mr的压缩 今日提纲 一.流量汇总排序的实现 1.需求 对日志数据 ...

  7. EnterpriseDb公司的Postgres Enterprise Manager 安装图解

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL基础知识与基本操作索引页     回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackg ...

  8. 仙人掌&圆方树

    仙人掌&圆方树 Tags:图论 [x] [luogu4320]道路相遇 https://www.luogu.org/problemnew/show/P4320 [ ] [SDOI2018]战略 ...

  9. python基础学习1-SET 集合

    # -*- coding:utf-8 -*- set集合 无序不重复的序列 se = {"a","b","c"} #创建SET集合 prin ...

  10. underscore.js 分析6 map函数

    作用:通过转换函数(iteratee迭代器)映射列表中的每个值产生价值的新数组.iteratee传递三个参数:value,然后是迭代 index. _.map([1, 2, 3], function( ...