usaco第二题,中文版翻译在洛谷P9975
此题算法:贪心算法
贪心策略:天数越大,奶牛越少,所以我们让天数最多。
思路:我先算出了1的区间,也就是连续1的数量(这个数值的变量名设置为y),连续一的数量,分为两种情况:一种是非边界的,一种是含边界的
我们通过y来算出最大的天数:非边界的公式:day=(y-1)//2(因为非边界的牛可以传染到两边的牛),含边界的公式:day=y-1(含边界的只能传染到他的左边或者右边一头牛)
我们将这些day存入一个列表(叫作daylist),在daylist里面找到min(daylist)为什么要在这里面找到最小值呢?因为所有感染的奶牛(连续1的区间)都是同时在蔓延疾病的,如果不是最小值,那么疾病就会“溢”出来,没有奶牛可以传染了。最后cownum(奶牛数量)表示为y/(1+2minday),这个公式的解释是:y是感染的奶牛群体,1+2minday是一头中间的奶牛传染给两边的奶牛乘以它的最小天数。注意这个公式返回的答案的类型float,我们要math.ceil(返回的值)
这里还有一个需要注意的,全一与全零的情况,你可以做一个特判,但是我用的是在原来的列表里面添加一个很大的数,防止全零的情况
多说无用,来看代码吧
# 9975 第二道题
import math
n=int(input())
data=input()
data="0"+data+"0"# 字符串最左边与最右边没有字符
dylist=[99999999999999999999999999999999999999]# 防止全0的情况,minday为99999999999999999999999999
ylist=[]# 连续1的数量的列表
for i in range(1,len(data)-1):
if data[i-1]=="0" and data[i]=="1":# 连续1的开始
bjt=i# 1的开头
if data[i]=="1" and data[i+1]=="0":# 结束
ylist.append(i-bjt+1)
if bjt==1 or i==n:
day=i-bjt# 1 的长度 含边界 day为最大天数
else:
day=(i-bjt)//2# 非边界 day为最大天数
dylist.append(day)
minday=min(dylist)# day为最大值dylist的最小值,因为大了就超出范围了
cownum=0
for i in ylist:
cownum+=math.ceil(i/(1+2*minday))
print(cownum)