程序设计方法——贪心算法PPT教学课件

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《程序设计实践》
程序设计方法之 贪心法
2020/12/12
1
贪心法
概念:贪心法( Greedy algorithm),又 称贪心算法,是一种在每一步选择中都采 取在当前状态下最好或最优(即最有利) 的选择,从而希望导致结果是最好或最优 的算法
每一步上都要保证能获得局部最优解,但由此 产生的全局解有时不一定是最优的
反证法:
假设存在正整数n,使得有办法将25美分、10美分、5美分 和1美分硬币用少于贪心算法所求出的硬币去找n美分零钱。
首先,在这种找n美分零钱的最优方式中使用25美分硬币的 个数q′,一定等于贪心算法所用25美分硬币的个数。
为了说明这一点,注意贪心算法使用尽可能多的25美分硬币,所 以q′≤q。但是q′也不能小于q。假如q′小于q,需要在这种最优方式 中用10美分、5美分和1美分硬币至少找出25美分零钱。而根据引 理1,这是不可能的。
cin >> n;
2020/12/12
11
参考代码(续)
//读入数据,并得到最终每堆石子的数量nAverage; for (i = 0; i < n; i++) {
cin >> heap[i]; nTotal += heap[i]; } nAverage = nTotal / n;
int now, next; //当前的石子堆now,now右边的石子堆next int nStart = 0; //记录得到最少移动牌数的方案中起点位置
输入数据保证最后可以达到每堆石子的个 数相等
2020/12/12
9
解题思路
本题模型与均分纸牌很相似
均分纸牌:一条直线 石子移动:环
参考上一题的方法,尝试从任何一堆纸牌 出发,求得当前的最小移动的石子数
从不同的石子堆出发最小移动石子数一样么? 如何得到全局最优解
枚举每个出发点,从中找一个移动石子数目最小的。
2020/12/12
12
一般说来,时间复杂度较低,算法实现也比较 容易
2020/12/12
2
问题1:找零钱
找零钱找给顾客。手头有quarters ($0.25), dimes ($0.10), nickels ($0.05) and pennies ($0.01),将 钱找给顾客,但是需要你找给顾客的钱币数量最 少。
2020/12/12
10
参考代码
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <cmath> #include <iostream>
using namespace std; #define MAXHEAP 1100
2020/12/12
5
找零钱问题(续)
找零钱找给顾客。手头有quarters ($0.25), dimes ($0.10), nickels ($0.05) and pennies ($0.01),将钱 找给顾客,但是需要你找给顾客的钱币数量最少。
如果缺少nickels($0.05)的硬币,如何找给 顾客,才能使钱币数量最少?
引理1:
若n是正整数,则用25美分、10美分、5美分和 1美分等尽可能少的硬币找出的n美分零钱中, 至多有2个10美分、至多有1个5美分、至多有4 个1美分硬币,而不能有2个10美分和1个5美分 硬币。用10美分、5美分和1美分硬币找出的零 钱不能超过24美分。
2020/12/12
4
贪心法证明(续)
int main() {
int n, heap[MAXHEAP], tmpHeap[MAXHEAP]; // minMoves表示最小移动的牌数,初始化为最大整数 int nTotal = 0, nAverage = 0, minMoves = 0x7FFFFFFF, nMoves; int i, j;
2020/12/12
7
解题Βιβλιοθήκη Baidu路
确定最终每堆纸牌上的纸牌数目 从一个端点出发沿着一个方向移动纸牌,
每次移动后确保当前这堆纸牌上的数目是 最终每堆纸牌数目
注意:可以移动负数
最优方案,证明?
代码略
2020/12/12
8
问题3:石子移动
有N堆石子排成一个圈,第i堆石子有ai个石 子。每堆石子均可被移动到相邻的堆,请 问要使得所有堆石子的个数均相等,最少 需要移动多少个石子。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌 数都一样多。
例如 N=4,4 堆纸牌数分别为: ① 9 ② 8 ③ 17 ④ 6 移动3次可达到目的: 从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ② (9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。
这两种方式中有同样多的25美分硬币,所以在这两种方式中 10美分、5美分和1美分硬币的总值一定相等,并且这些硬 币的总值不超过24美分
10美分硬币的个数一定相等,因为贪心算法使用尽可能多的 10美分硬币。而根据引理1,当使用尽可能少的硬币找零钱 时,至多使用1个5分硬币和4个1分硬币,所以在找零钱的 最优方式中也使用尽可能多的10美分硬币。类似地,5美分 硬币的个数相等;最终,1美分的个数相等。
如果要找给顾客0.3元钱,最优方案? 贪心法方案:0.25 +0.01 * 5 0.1 * 3
2020/12/12
6
问题2:均分纸牌
均分纸牌(1040) 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但
纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移 动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的 堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上; 其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
解法:
枚举法:枚举所有可能,从中找出钱币数量最少的方 案
贪心法:尽可能的先找quarters,然后是dimes, nickels, pennies
这样找出的钱币的个数一定最少么????
2020/12/12
3
贪心法证明:
方便起见上述硬币表示为25美分,10美分, 5美分,1美分,待找钱为n美分。
相关文档
最新文档