python贪心算法——以“修理牛棚”题目为例

时间:2022-11-23 20:05:16

题目描述

在一个月黑风高的暴风雨夜,Farmer John 的牛棚的屋顶、门被吹飞了 好在许多牛正在度假,所以牛棚没有住满。

牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。

自门遗失以后,Farmer John 必须尽快在牛棚之前竖立起新的木板。他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 Farmer John 想将他购买的木板总长度减到最少。

给出 $m,s,c$,表示木板最大的数目、牛棚的总数、牛的总数;以及每头牛所在牛棚的编号,请算出拦住所有有牛的牛棚所需木板的最小总长度。

输入格式

一行三个整数 $m,s,c$,意义如题目描述。
接下来 $c$ 行,每行包含一个整数,表示牛所占的牛棚的编号。

输出格式

输出一行一个整数,表示所需木板的最小总长度。

样例 #1

样例输入 #1

4 50 18
3 
4 
6 
8 
14
15 
16 
17 
21
25 
26 
27 
30 
31 
40 
41 
42 
43

样例输出 #1

25

提示

【数据范围】
对于 $100%$ 的数据,$1\le m \le 50$,$1\le c \le s \le 200$。

USACO Training Section 1.3

————————————————————————————————
本文接下来将先给出代码,之后进行一个详细的介绍:

m, s, c = input().split()
m, s, c = int(m), int(s), int(c)
"""
m:木板的最大数量
s:牛棚的总数
c:牛的总数
"""
is_cow = []

for i in range(c):
    num = int(input())
    is_cow.append(num)

is_cow.sort()

c_li = []  # c为a-b
for i in range(len(is_cow)-1):
    c_li.append(is_cow[i+1]-is_cow[i])

c_li.sort()

if m<=len(is_cow)-1:
    sum_li = 1
    for i in range(m-1):
        del c_li[-1]
        sum_li += 1

    print(sum(c_li)+sum_li)
else:
    print(len(is_cow))
  1. m,s,c为题目中给出的条件
  2. 根据题目中给出的条件,我们需要将给出有牛的棚放在一个列表里面以让我们便于观察和操作
  3. 这里注意,就像日期一样,不能简单用减法来表示数量,需要加1,本文的sum_li即以1开头,后续直接方可直接减法
  4. 注意列表需要sort()一下,否则会出现wa的情况
  5. 同时下面需要注意加if判断,如果木板的数量小于牛的数量,因此可以用本文设计的算法,否则答案直接判定为牛的数量即为答案,不加判断会re
  6. 中间实现的过程有一个取巧的办法,如果两个棚号之间的距离较长,那么就放弃这段距离,相对应的应该在原长度上加1。断开之后,两个点因为距离太大被放弃,但是后面这个点就没有一点遮拦,仍需要一个木板去压一下。