洛谷贪心算法训练(python实现)

137 阅读3分钟

贪心算法的理解:

这种题目不会有很明显的正确性证明,因为可能从题目的意思好像不能完全符合,但其中的奥妙需要自己去理解,没有固定的套路

1.删数问题

www.luogu.com.cn/problem/P11…

这个问题主要是需要进行贪心,删除左边很大的数,看到很多人都是贪心将前面大的数给删掉让出来给小的数,首先可以保证前面的值一定是很大的值就行.但是后缀处理0也是一个问题,要将0

这里学习到了如何在python中移动数组:(以下为删除第i个字符的example)

x =x[0:i]+ x[i+1:]        #

处理前导0:

while(flag<len(zifu) and zifu[flag]=='0'):
    flag+=1         #使用flagif(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 -= 1flag=0
while(flag<len(zifu) and zifu[flag]=='0'):
    flag+=1         #使用flag
​
if(flag==len(zifu)):
    print("0")
else:
    print(zifu[flag:])

2.永夜的报应

www.luogu.com.cn/problem/P55…

对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.骑士的工作

www.luogu.com.cn/problem/P26…

这道题就是要找到砍掉恶龙头最近的骑士,可以都从小到大排序,从小到大开始砍,如果最后没有把所有龙头都砍完就算输,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.]均分纸牌

www.luogu.com.cn/problem/P10…

这道题就是贪心问题,我们不断的把前面的牌全部分给后面,而不能从后面的牌堆分给前面,因为题目说了牌总数满足要求,于是最后总会有解(必是最优解),之后从第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)