问题4来自CCC 2019
问题描述 你计划去参观N个旅游景点。景点编号从1到N 必须按此顺序访问。你每天最多可以参观K个景点,并计划旅行 以尽可能少的天数。 在这些限制条件下,你想找到一个在景点之间有很好平衡的时间表 每天访问。准确地说,我们分配了一个分数 给一个时间表,每天 给出的分数等于当天参观的所有景点的最高分数。最后 每一天都要加总,得出日程的总分。最大可能总数是多少 用最少的时间安排? 输入规范 第一行包含两个空格分隔的整数N和K(1≤K≤N≤10^6) ). 下一行包含N个空格分隔的整数ai(1≤ai≤10^9) ). 15分中有3分,2K≥N。 对于15个可用标记中的另外3个,K≤100和N≤10^5 . 输出规格 输出单个整数,最大可能的总分。 样本输入 5 3个 2 5 7 1 4 样本输入输出 12 样本输入输出说明 我们需要至少两天的时间游览所有景点,因为我们不能游览所有的景点 有一天。 第一天参观前两个景点得5分,最后三个景点得5分 第二天得7分,总分12分。 第一天游览三个景点,第二天游览两个景点,这是唯一可以 在尽可能短的天数内就诊,总分为7+4=11。在
我的方法 使用递归遍历初始吸引力,然后在第二天发送部分,并在每个递归中找到最高分数
def scores(things, att, days):
minper = attractions(att,row1[1])
if att <= 0:
return 0, False
if days > minday:
return 0, True
else:
maxscore = 0
for y in range(minper,row1[1]+1):
score, more = scores(things[y:],att-y,days+ 1)
if not(more):
score += max(things[:y+1])
if score >= maxscore:
maxscore = score
return maxscore, False
def attractions(attr,maxper):
if (attr % maxper) == 0 and attr > 0:
return maxper
return (attr % maxper)
row1=(input()).split(" ")
places=(input()).split(" ")
for x in range(len(row1)):
row1[x] = int(row1[x])
for x in range(len(places)):
places[x] = int(places[x])
if (row1[0]/row1[1])%1 == 0:
minday = int(row1[0]/row1[1])
else:
minday =(row1[0]//row1[1]) + 1
if minday !=1:
maxscore = 0
for x in range(attractions(row1[0],row1[1]),row1[1]+1):
score, more = scores(places[x:],row1[0]-x,1)
if not(more):
score += max(places[:x])
if score >= maxscore:
maxscore = score
print(maxscore)
else:
print(max(places))
这些问题的测试用例包括N为1000000,K为999999的数字,这意味着两天(最短天数)每天可能的出行次数为1999999999998。。。99999 8,2 999999,1,这对于这种方法来说太长了,还有另一种情况,例如,N=51,K=10,所以它可以是10,10,10,10,1或10,1,10,10,10,10,10,10或者它也可以是9,9,9,9,9,9,6等等,但是它覆盖了所有的数字排列,这些数字加起来就是最小天数。如何更好地优化这一点,或者有更好的方法在1秒内完成。在
以下是我的建议(一种天真的方法):
特殊情况:2K>;N(最少天数=2)
当只有两个假期时,考虑到这两天有一个共同的重叠点,在任何一天都可以看到景点,算法可以大大简化。此外,还有第一天必须参观的主要景点和第二天必须参观的尾随景点。因此,我们正在寻找领先、落后和普通群体之间的前2大吸引力。领头组和尾随组最多只能有一个“顶级吸引力”,普通组最多可以有两个。在
因此,只有4种方式可以将前两大景点分布在三个组别之间:
取max(lead)、max(tail)和common的top2之间的前2个值,我们将得到最好的组合,如这里用4个模拟值所示。在
^{pr2}$其他情况下的更好算法
为了改进上述暴力行为,我们可以计算每一个景点在一天中的第一个景点的部分行程分数。这可以从最后一个逐步计算到第一个。那么第一个景点的旅行分数就是答案。在
注意,可以通过执行边缘情况的impler计算,例如“最小访问”范围内的第一次和最后一次访问。我认为这只在K非常大(但不大于N/2)且N mod K接近K的情况下才有意义
相关问题 更多 >
编程相关推荐