python 基础知识点(蓝桥杯python科目个人复习计划42)

今日复习内容:重新学习一下贪心算法

今天做题的时候,想了半天贪心算法,结果没全想出来,所以菜就多练,重新学一下呗。

贪心算法是一种常见的算法范式,通常用于求解最优化过程。在每一步的选择中,贪心算法总是做出当前看起来最优的选择,而不考虑当前选择之后的结果。贪心算法的核心思想是通过局部最优解来寻求全局最优解。

贪心算法具有以下特点:

(1)局部最优性:每一步选择都是局部最优的,即当前情况下的最优选择。

(2)不可回退行:一旦做出了选择,就不会再改变,这意味着贪心算法做出的选择是永久性的,不会考虑后续的情况。

(3)简单高效:贪心算法通常实现简单,执行效率高,适用于解决某些特定类型的问题。

贪心算法通常适用于满足以下条件的问题:

(1)问题可以通过局部最优解达到全局最优解;

(2)问题的求解过程可以划分为一系列步骤,每一步选择都是局部最优的,且当前选择不影响后续步骤的选择;

(3)问题的求解过程不需要回退或者回溯,即一旦做出选择就无需再修改。

实例:

(1)找零问题:给定一定面额的货币,如何用最少的数量的货币来完成找零?贪心算法可以从面额最大的货币开始,逐步选取,直到找零完成。

(2)背包问题:给定一个背包和一组物品,每个物品有自己的价值和重量,如何在背包容量限制下装入尽可能多的价值?如果物品可以分割,可以使用贪心算法按照单位重量的价值从大到小选择物品装入背包。

(3)活动选择问题:给定一系列活动,每个活动都有开始时间和结束时间,同时只能进行一个活动,如何安排活动使得参加的活动数量最多?贪心算法可以按照结束时间从早到晚排序,然后依次选择结束时间最早且与之前活动不冲突的活动。

值得注意的是,贪心算法虽然较简单,但并不是所有问题都适合用贪心算法求解。在某些情况下,贪心算法可能无法得到最优解,或者需要证明才能确保其正确性。因此,在应用贪心算法时,需要谨慎选择问题和验证算法的有效性。

我找了好多题,我觉得多做几个题,应该就OK了。

例题1:答疑

有n位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。

老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑,一位同学答疑的过程如下:

1.首先进入办公室,编号位i的同学需要si毫秒的时间。

2.然后同学问问题老师解答,编号位i的同学有ai毫秒的时间。

3.答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可以忽略。

4.最后同学收拾东西离开办公室,需要ei毫秒的时间,一般需要10秒,20秒或30秒,即ei取值为10000,20000或30000。

一位同学离开办公室后,紧接着下一位同学就可以进办公室了。

答疑从0时刻开始,老师想合理的安排答疑的顺序,使得同学们在课程群里面发消息的时刻之和最小。

输入描述:

输入第一行包含一个整数n,表示同学的数量;

接下来n行,描述每位同学的时间,其中第i行包含三个整数si,ai,ei,意义如上所述。

其中,1 <= n <= 1000,1 <= si <= 60000,1 <= ai <= 10^6,ei 一定为10000,20000,30000之一。

输出描述:

输出一个整数,表示同学们在课程群里面发消息的时刻之和最小是多少?

分析:我写出前三个同学的情况

第一个同学:sum1(time) = s1 + a1 + e1

第二个同学:sum2(time) = s2 + a2 + s1 + a1 + e1

第三个同学:sum3(time) = s3 + a3 + s2 + a2 + e2 + s1 + a1 + e1

我们要求的是s1 + a1 + e1 ,s2 + a2 + e2,s3 + a3 + e3谁最小

参考答案:

n = int(input())
ls = []
for i in range(n):
    ls.append(list(map(int, input().split())))
count = 0
t = 0
ls.sort(key=lambda x: sum(x))

for i in range(n):
    t += sum(ls[i])
    count += t - ls[i][-1]

print(count)

运行结果:

例题2:重复字符串

题目描述:

如果一个字符串s恰好可以由某个字符串重复k次得到,我们就称s是k次重复字符串。例如abcabcabc可以看作abc重复3次得到,所以abcabcabc是3次重复字符串。

同理,aaaaaa既是2次重复字符串,又是3次重复字符串和6次重复字符串。

现在给定一个字符串s,请你判断至少要修改其中几个字符串,可以使s变成一个k次字符串?

输入描述:

输入第一行包含一个整数k;

第二行包含一个只含小写字母的字符串s。

其中,1 <= k <= 10^5,1<= |s| <= 10^5,其中|s|表示s的长度。

输出描述:

输出一个整数代表答案,如果s无法修改成k次字符串,就输出-1。

参考答案:

k = int(input())
s = input()
l = len(s) // k
num = 0
for i in range(l):
  ls = s[i:len(s):l]
  lis = {}
  for i in ls:
    lis[i] = lis.get(i,0) + 1
  lis = sorted(lis.items(),key = lambda x:x[1])
  for i,j in lis[:-1]:
    num += j
print(num)

OK,我做不下去了,这篇就这样吧,下一篇继续!

  • 35
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值