华为机试:缓存转发数据包统计

博客内容讲述了如何使用动态规划方法解决一个涉及网络数据包转发的问题。具体情境为有k个节点的转发队列,每个节点具有转发能力和缓存能力,且可能存在节点故障。在两轮操作中,计算最少可以收到多少数据包。样例给出了不同场景的解答,并提供了一个Python解决方案作为参考。
摘要由CSDN通过智能技术生成

题目

有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.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值