小易觉得高数课太无聊了,决定睡觉。不过他对课上的一些内容挺感兴趣,所以希望你在老师讲到有趣的部分的时候叫醒他一下。你知道了小易对一堂课每分钟知识点的感兴趣程度,并以分数量化,以及他在这堂课上每分钟是否会睡着,你可以叫醒他一次,这会使得他在接下来的k分钟内保持清醒。你需要选择一种方案最大化小易这堂课听到的知识点分值。
输入描述:
第一行 n, k (1 <= n, k <= 105) ,表示这堂课持续多少分钟,以及叫醒小易一次使他能够保持清醒的时间。
第二行 n 个数,a1, a2, ... , an(1 <= ai <= 104) 表示小易对每分钟知识点的感兴趣评分。
第三行 n 个数,t1, t2, ... , tn 表示每分钟小易是否清醒, 1表示清醒。
输出描述:
小易这堂课听到的知识点的最大兴趣值。
输入例子1:
输出例子1:
16
# 分析了题目,用了数学思维解决问题。
# 遍历每一个 t (叫醒的时刻),求得当时的知识点分值,最后取最大。
# 分值 = sum(scores * awake) + sum(scores[t:t+k-1]) - sum(scores[t:t+k-1] * awake[t:t+k-1]),把 scores 列表和 awake 列表对应写在一起,就能想明白了。
# 算法复杂度太高,已超时。AC仅仅0.5。
import sys
n, k = map(int, sys.stdin.readline().strip().split())
scores = sys.stdin.readline().strip().split()
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = []
for t in range(n):
res1, res2, res3 = 0, 0, 0
for i in range(n):
res1 += scores[i] * awake[i]
if t + k <= n:
for j in range(t, t+k):
res2 += scores[j] * awake[j]
for m in range(t, t+k):
res3 += scores[m]
else:
for j in range(t, n):
res2 += scores[j] * awake[j]
for m in range(t, n):
res3 += scores[m]
result.append(res1 + res3 - res2)
print(max(result))
# 略微有所优化,但依旧不起本质性作用。
import sys
n, k = map(int, sys.stdin.readline().strip().split())
scores = sys.stdin.readline().strip().split()
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = 0
start = 0
for index in range(n): # 不是从头开始遍历,而是从第一个 awake 为0 的时候开始遍历。
if awake[index]:
start += 1
else:
break
for t in range(n):
res1, res2, res3 = 0, 0, 0
for i in range(n):
res1 += scores[i] * awake[i]
if t + k <= n:
for j in range(t, t+k):
res2 += scores[j] * awake[j]
for m in range(t, t+k):
res3 += scores[m]
else:
for j in range(t, n):
res2 += scores[j] * awake[j]
for m in range(t, n):
res3 += scores[m]
tmp = res1 + res3 - res2
result = tmp if tmp > result else result # 更新最大值,不存储每个 t 对应的 tmp。
print(result)
# 略微有所优化,依旧不起本质作用。(仅提升到了 0.6)
import sys
n, k = map(int, sys.stdin.readline().strip().split())
scores = sys.stdin.readline().strip().split()
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = 0
start = 0
for index in range(n): # 从第一个不清醒时刻开始遍历即可。
if awake[index]:
start += 1
else:
break
for t in range(start, n-k+1): # 到 t-k 时刻即可,因为后面再遍历,一定不如 n-k 时叫醒知识点值大。
res1, res2, res3 = 0, 0, 0
for i in range(n):
res1 += scores[i] * awake[i]
for j in range(t, t+k):
res2 += scores[j] * awake[j]
for m in range(t, t+k):
res3 += scores[m]
tmp = res1 + res3 - res2
result = tmp if tmp > result else result # 更新最大值,不存储每个 t 对应的 tmp。
print(result)
下面参考牛客网友:瞌睡_牛客网
n, k = list(map(int, input().split()))
scores = list(map(int, input().split()))
awake = list(map(int, input().split()))
# 先计算最初所有清醒时刻分值之和,这里做了一个很巧妙的事情:把清醒时刻的分值加了之后,把其分值置零(为了防止后续再次重复加,大吼一声 666!)
initi_score = 0
for i in range(n):
if awake[i]:
initi_score += scores[i]
scores[i] = 0 # 操作666
# 计算因为叫醒他,分值增加的那一部分
max_boost_score = 0
for t in range(n): # 提前结束循环的条件,注意:不一定是从非清醒状态开始加,见下面测试用例。
if not awake[t]: # 从非清醒状态叫醒才能最佳
boost_score = sum(scores[t: min(t+k, n)])
max_boost_score = max(boost_score, max_boost_score)
if t > n - k + 1:
break
result = initi_score + max_boost_score
print(result)
1. 输入输出的问题——用 input 来写(前面一篇用的 sys.stdin.readline())
(参考:瞌睡_网易笔试题_牛客网)
# 单行输入,此时有两个元素,用list()把它变成了列表
nk = list(map(int, input().split()))
# 把列表两个元素取出来
n = nk[0]
k = nk[1]
# 再获取第二行输入
a = list(map(int, input().split()))
# 获取下一行输入(即第三行)
t = list(map(int, input().split()))
2. input 的用法
(1) Python2 是 raw_input();Python3 是 input() 。
(参考:Python3 input() 函数)
(参考:Python input() 函数)
(参考:Python2.x 和 Python3.x 中 raw_input( ) 和 input( ) 区别)
(2) Python3 中 input 读出来的一切信息都是 string 类型,若想转换成 int 型,可以用 eval() 或者 int()。
(3) 多个参数输入
① 输入个数确定时
>>> a, b, c = input('...>').split()
...>11 22 33
# 那么有:
a = '11'
b = '22'
c = '33'
② 输入个数不确定时,把它们放在一个列表里面
>>> list = []
>>> list = input('...>').split()
...>11 22 33 44
# 那么有:
['11', '22', '33', '44']
(参考:python input 详解)