洛谷贪心算法训练(python实现)
贪心算法的理解:
这种题目不会有很明显的正确性证明,因为可能从题目的意思好像不能完全符合,但其中的奥妙需要自己去理解,没有固定的套路
1.删数问题
https://www.luogu.com.cn/problem/P1106
这个问题主要是需要进行贪心,删除左边很大的数,看到很多人都是贪心将前面大的数给删掉让出来给小的数,首先可以保证前面的值一定是很大的值就行.但是后缀处理0也是一个问题,要将0
这里学习到了如何在python中移动数组:(以下为删除第i个字符的example)
x =x[0:i]+ x[i+1:] #
处理前导0:
while(flag<len(zifu) and zifu[flag]=='0'):
flag+=1 #使用flag
if(flag==len(zifu)):
print("0")
else:
print(zifu[flag:])
完整代码
zifu =input()
k = int(input()) #输出k值
while k>0: #进行k次遍历,贪心
for i in range(len(zifu)-1): #使用了n个
if(zifu[i]>zifu[i+1]):
zifu =zifu[0:i]+ zifu[i+1:] #
break
k -= 1
flag=0
while(flag<len(zifu) and zifu[flag]=='0'):
flag+=1 #使用flag
if(flag==len(zifu)):
print("0")
else:
print(zifu[flag:])
2.永夜的报应
https://www.luogu.com.cn/problem/P5514
对01的异或来说,就是求差,由于要找到
当a第i位为0,b第i位为0时,第i位在加/异或下的答案:0+0=0 0^0=0
当a第i位为0,b第i位为1时,第i位在加/异或下的答案:0+1=1 0^1=1
当a第i位为1,b第i位为0时,第i位在加/异或下的答案:1+0=1 1^0=1
当a第i位为1,b第i位为1时,第i位在加/异或下的答案:1+1=2 1^1=0
总的来说就是将所有数都异或起来的值必定小于相加.
3.骑士的工作
https://www.luogu.com.cn/problem/P2695
这道题就是要找到砍掉恶龙头最近的骑士,可以都从小到大排序,从小到大开始砍,如果最后没有把所有龙头都砍完就算输,python中排序可以对指定范围内(第1个到第10个数)进行排序:
a =[0,-1,2,5,62,3]
a[1:] = sorted(a[1:]) #就是只对1到后面的进行排序那是可以的
print(a) # [0, -1, 2, 3, 5, 62]
这样就实现了部分排序的功能,下面是使用正常贪心的做法:
n,m = map(int,input().split())
cost = [0 for i in range(n)]
value = [0 for i in range(m)]
for i in range(n):
cost[i] =int(input())
for i in range(m):
value[i] =int(input())
cost.sort()
value.sort()
flag=0
flag1 =0
sumvalue=0
while(flag<n):
while(flag1<=(m-1) and value[flag1]<cost[flag]): #需要首先判断是否数组溢出了
flag1+=1
if(flag1>=m):
sumvalue=0
break
sumvalue+=value[flag1]
flag1+=1
flag+=1
if(flag1>=m):
break
if(flag!=n):
print("you died!")
else:
print(sumvalue)
其他思路:
这道题可以使用优先队列,构建两个队列,根据两个队列是否为空的情况进行输出
4.]均分纸牌
https://www.luogu.com.cn/problem/P1031
这道题就是贪心问题,我们不断的把前面的牌全部分给后面,而不能从后面的牌堆分给前面,因为题目说了牌总数满足要求,于是最后总会有解(必是最优解),之后从第0堆依次移动至第n个堆,这样可以保证是最小的,而且不用管前面的值.
N =int(input())
A = [0 for i in range(N+1)]
A[0:N] = list(map(int,input().split()))
sumvalue = sum(A)/N
for i in range(N):
A[i] = int(A[i]-sumvalue)
ans=0
for i in range(N):
if(A[i]!=0): #
A[i+1]+=A[i]
ans+=1
print(ans)