贪婪算法
Part 1
贪婪算法简介
贪婪算法是从某一个初始状态登程,每次通过选取部分最优解向指标后退,并最终冀望获得整体最优解的一种算法。由这个定义可知,贪婪抉择规范就是抉择“以后最好”的决策,贪婪算法依据这个规范进行决策,将原问题变成一个类似但规模更小的子问题,而后每一步选出来的肯定是原问题整体最优解的一部分。
如果一个问题贪婪后只剩下一个子问题且有最优子结构,那么该问题就能够应用贪婪算法。当一个问题的整体最优解蕴含其子问题的最优解时,咱们称次问题具备最优子结构性质。
Part 2
解题个别步骤
1、设计数据找法则;
2、进行贪婪猜测;
3、正确性证实(包含列举反例和严格的 数学证实);
4、程序实现。
Part 3
例题 (洛谷 P1080 国王游戏):
题目形容
恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手下面别离写下一个整数,国王本人也在左、右手上各写一个整数。而后,让这 n 位大臣排成一排,国王站在队伍的最后面。排好队后,所有的大臣都会取得国王奖赏的若干金币,每位大臣取得的金币数别离是:排在该大臣后面的所有人的左手上的数的乘积除以他本人右手上的数,而后向下取整失去的后果。
国王不心愿某一个大臣取得特地多的奖赏,所以他想请你帮他重新安排一下队伍的程序,使得取得奖赏最多的大臣,所获奖赏尽可能的少。留神,国王的地位始终在队伍的最后面。
输出格局
第一行蕴含一个整数 n,示意大臣的人数。
第二行蕴含两个整数 a 和 b,之间用一个空格隔开,别离示意国王左手和右手上的整数。
接下来 n 行,每行蕴含两个整数 a 和 b,之间用一个空格隔开,别离示意每个大臣左手和右手上的整数。
输入格局
一个整数,示意重新排列后的队伍中获奖赏最多的大臣所取得的金币数。
输入输出样例
阐明 / 提醒
【输入输出样例阐明】
按 1、2、3 这样排列队伍,取得奖赏最多的大臣所取得金币数为 2;
按 1、3、2 这样排列队伍,取得奖赏最多的大臣所取得金币数为 2;
按 2、1、3 这样排列队伍,取得奖赏最多的大臣所取得金币数为 2;
按 2、3、1 这样排列队伍,取得奖赏最多的大臣所取得金币数为 9;
按 3、1、2 这样排列队伍,取得奖赏最多的大臣所取得金币数为 2;
按 3、2、1 这样排列队伍,取得奖赏最多的大臣所取得金币数为 9。
因而,奖赏最多的大臣起码取得 2 个金币,答案输入 2。
【数据范畴】
对于 20% 的数据,有 1≤ n≤ 10,0 < a,b < 8;
对于 40% 的数据,有 1≤ n≤20,0 < a,b < 8;
对于 60% 的数据,有 1≤ n≤100;
对于 60% 的数据,保障答案不超过 10^9;
对于 100% 的数据,有 1 ≤ n ≤1,000,0 < a,b < 10000。
Part 4
解题思路
无妨先探讨相邻的二元组。由题意可知,相邻两个大臣替换地位不会对后面和前面的其他人的金币数造成影响。也就是说相邻两人地位替换只会对这两个人产生影响咱们以此为切入点,剖析调换相邻的两个人对答案的影响。
设这两个人地位别离为 i 和 i +1,左手数字为 a[i] 和 a[i+1],右手数字为 b[i] 和 b[i+1],两人的金币数为 w[i] 和 w[i+1]。记 P[i]=a[1]a[2]a[3]…a[i]。
未调换程序时,k1=w[i]=P[i-1]/b[i]; k2=w[i+1]=P[i-1]*a[i]/b[i+1]; 则
ans1=max(k1,k2)
调换程序后 k3=P[i-1]/b[i+1]; k4=P[i-1]*a[i+1]/b[i]; 则 ans2=max(k3,k4)
显然有 k1<k4,k3<k2; 如果 ans1<ans2, 那么必有 k2<k4。化简可得 a[i]b[i]<a[i+1]b[i+1];
所以,为了 ans 取到最小值,咱们须要将 a[i]b[i] 较小的放在后面那么咱们以 a[i]b[i] 为关键字排序即可。同时,统计答案时肯定不要忘了写高精度。
小结
贪婪算法的外围问题是抉择能产生问题最优解的最优度量规范,即具体的贪婪策略。
特点是快,在运行过程中无回溯过程,每一步都是以后的最佳抉择
相干举荐:
视频解说:对于【暴力递归算法】你所不晓得的思路
刷 Github 时发现了一本阿里大神的算法笔记!标星 70.5K
END
看完三件事❤️
========
如果你感觉这篇内容对你还蛮有帮忙,我想邀请你帮我三个小忙:
点赞,转发,有你们的『点赞和评论』,才是我发明的能源。
关注公众号『Java 斗帝』,不定期分享原创常识。
同时能够期待后续文章 ing????