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

博客围绕洛谷贪心算法训练,用Python实现多个题目。包括删数问题,需贪心删左边大数并处理前导0;永夜的报应涉及01异或与相加;骑士的工作要找砍恶龙头最近的骑士,可排序或用优先队列;均分纸牌是贪心分配纸牌问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

洛谷贪心算法训练(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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值