贪心
贪心:把整体问题分解成多个步骤,在每个步骤都选取当前步骤的最优方案,直到所有步骤结束;每个步骤不会影响后续步骤。
核心性质:每次采用局部最优,最终结果就全局最优。
如果题目满足上述核心性质,则可用贪心求解。
例:最少钱币支付问题
假设有三种钱币:1元、2元、5元,数量不限,现在需支付m元,要求钱币数目最少,应如何支付?
局部最优:要保证硬币尽可能少,所以当前尽可能选择大面值硬币
此问题只要采用局部最优就能得到全局最优
如果把钱币面值改成1元、2元、4元、5元、6元,现需支付9元,按贪心方法:6+2+1需要3个币
但是最优结果:4+5
那么如何判断是否能用贪心?
1、最优子结构性质:
当一个问题的最优解包含子问题的最优解,则称之为具有最优子结构性质。
2、贪心性质选择:可以通过局部最优的选择得到全局最优
具体问题怎么做?
1、经验积累各种类型的贪心问题
2、举反例
经典贪心问题
532纪念品分组
题目链接:532纪念品分组
每组最多两件,价值之和不超过w
尽可能不浪费空间:大的和小的凑在一起
w = int(input())
n = int(input())
a = []
for i in range(n):
a.append(int(input()))
a.sort()
ans = 0
l , r = 0 , n - 1
while True:
#如果l、r相等说明只剩下一个元素,将其加入答案并跳出循环
if l == r :
ans += 1
break
#如果l大于r,说明遍历完成跳出循环
if l > r:
break
#如果 a[l] + a[r] <= w,说明当前指向的两个元素的和小于等于w,将l右移一位,r左移一位,答案加1
if a[l] + a[r] <= w:
l += 1
r -= 1
ans += 1
else:#否则,r左移一位,答案加1
r -= 1
ans += 1
print(ans)
100
9
90
20
20
30
50
60
70
80
90
6
209翻硬币
题目链接:209翻硬币
s = list(input())
t = list(input())
n = len(s)
ans = 0
for i in range(n-1):
if s[i] != t[i]:
ans += 1
if s[i+1] == '*':
s[i+1] = 'o'
print(ans)
**********
o****o****
5