题目
有k个节点的转发队列,每个节点转发能力为m,缓存能力n (表示此节点可立即转发m个包,剩余的缓存,最多缓存n个包,再剩余的丢弃,缓存的包在下一轮继续转发)。另外, 此队列中某些节点可能因故障需要直接跳过转发,但不会有两个连续故障的节点。
现分两轮操作,第一轮向此队列发送a个数据包让其转发;第二轮,直接驱动让缓存的数据包继续转发。求两轮最后可能收到的最少数据包总个数(如果第二轮缓存仍有数据包,缓存包按丢弃处理)
1 <=k<=40
1 <= m,n<= 1000
1 <=a<= 1000
例如:有两个节点,节点1(转发能力m:50,缓存能力n:60)和节点2(m:30,n:25),发送包数为120,
在没有节点故障时:
输入
第一行队列长度K
第二行为k个节点转发能力数组,以空格分隔。m,n以逗号分隔,例如:
10,20 11,21 12,22
第三行数据包个数a
输出
输出
最少收到的包个数
样例1
输入: 2
50,60 30,25
120
输出: 55
解释: 参见题目中的图例,当第一个节点故障时,仅第二个节点转发,此时收到的包最少。
样例2
输入: 5
50,50 20,20 40,10 30,5 10,5
100
输出: 20
解释:第一轮跳过一个节点转发20缓存20。转发的20到最后一个节点转发10缓存5。
第二轮缓存的20转后转发的20到最后一个节点,加上此节点已经缓存的5,共25,但此节点只能转发10。
因此最后收到包个数最少为20个。
样例3
输入: 1
30,30
100
输出: 60
解释: 第一轮经过首节点转发30缓存30,第二轮缓存的转发30,两轮总共为60。
如果首节点故障直接跳过,则收到100, 因此最后最少值为60。
解答
典型的动态规划问题,最主要的是需要理解题目。
Python解决方案:
k = int(input())
nodes = input()
nodes = [[int(i) for i in x.split(",")] for x in nodes.split(" ")]
a = int(input())
a = [a, a] # 当前节点第一轮收到的转发量, a[0]表示上一节点不发生故障, a[1]表示上一节点发生故障
x = [0, 0] # 当前节点第一轮最小转发量
y = [0, 0] # 当前节点第二轮最小转发量
for node in nodes:
temp = y[0]
# 当前节点不发生故障(分上一节点不发生故障和发生故障两种情况,取两轮转发总量最小为该节点输出)
x0 = min(a[0], node[0])
y0 = min(min(a[0] - x0, node[1]) + y[0], node[0])
x1 = min(a[1], node[0])
y1 = min(min(a[1] - x1, node[1]) + y[1], node[0])
if (x0 + y0 < x1 + y1):
x[0], y[0] = x0, y0
else:
x[0], y[0] = x1, y1
# 当前节点发生故障(只有上一节点不发生故障一种情况)
x[1], y[1] = a[0], temp
a = x.copy() #特别注意
res = min(x[0]+y[0], x[1]+y[1])
print(res)
The End.