贪心算法
简单来说就是找到局部最优解.
1.找零钱问题
假设我们用硬币给顾客找零钱,那么我们如何使用最少的硬币找到满零钱,就可以用贪心算法来解决。首先我们得定义一个列表,里面储存了我们的硬币种类,做一些简单的判断,增加代码的健壮性,然后我们写主要代码,首先由于python的特性我们得从0开始计算,所以想从大往小比(先使用stored()进行排序)得先-1,接着判断我们输入的零钱是否大于要比的数,若小于直接i-与上一个硬币的种类进行比较,若小于进行整除处理,得出的结果就是这种硬币要找的个数,总零钱就得减去已经找了的零钱,如此循环就可以找出硬币数最少的结果。
def change():
d = [0.01,0.02,0.05,0.1,0.2,1]
while True:
try:
sum = float(input("输入要找的零钱"))
if sum <= 0:
print("错误")
else:
break
except:
print("错误")
i = len(d) - 1
while i>=0:
if sum >= d[i]:
n = int(sum/d[i])
sum = float("{:.2f}".format(sum - n*d[i]))
print("{}个{}硬币".format(n,d[i]))
i -= 1
change()
2.排队接水
题目如下图
此题也是简单的贪心算法,首先创建一个空列表,遍历将输入的n与m存入列表一一对应,再将列表从小到大排序,接着定义一个空列表用于存放等待时间总和,遍历直接输出列表的第一个数就是原始的位置,由于计算的是所有人的等待时间,那么下个人的等待时间就得加上个人的等待时间,最后输出总时间除于人数就是平均数。
n = int(input())
m = list(map(int,input().split()))
queue=[]
for i in range(n):
queue.append((i+1,m[i]))
queue.sort(key = lambda x:x[1])
sum = 0
for i in range(n):
print(queue[i][0],end=" ")
sum += queue[i][1]*(n-1-i)
print()
print("%.2f"% (sum/n))
3.阿里巴巴金币问题
题目如下图
这题跟找零钱类似,首先创建一个新列表,但是我们不仅要把输入的的金币个数和价值,还要输入每种金币的性价比,再根据性价比的从高到低排序,那么我们就可以跟找零钱类似一个一个比较,但不同的是这里有重量限制,所以我们得考虑重量不能超过,如果比较第一个可装的重量就不够,可以直接只拿性价比最高的金币,如果拿完性价比最高的还有多,那么就取拿性价比第二的,以此类推。
n,m=map(int,input().split())
lit=[]
for i in range(n):
m,v=map(int,input().split())
lit.append((m,v,v/m))#(v/m是性价比)
lit.sort(key=lambda x:x[2],reverse= True)
count = m
sumvalue = 0
for i in range(n):
if lit[i][0] <= count:
count -= lit[i][0]
sumvalue += lit[i][1]
else:
sumvalue += lit[i][2]*count
break
print("%.2f"%sumvalue)
4.最多比赛选择
这题同样先创建一个空列表,将输入的比赛开始结束时间存入列表,再用结束时间进行从小到大的排序,定义两个计数器,一个是可以参与的竞赛,另一个表示结束的时间,然后遍历列表,如果起始时间大于等于我们定义的结束时间,那么计数器+1,在把此比赛的结束时间赋予我们定义的结束时间计数器。当然这不是最优解,在洛谷上只能拿70,后面的运行时间超时了,个人水平有限。
n = int(input())
intervals = []
for _ in range(n):
a, b = map(int, input().split())
intervals.append((a, b))
intervals.sort(key=lambda x: x[1])
count = 0
end_time = 0
for start, end in intervals:
if start >= end_time:
count += 1
end_time = end
print(count)