题目描述
在通信系统中,一个常见的问题是对用户进行不同策略的调度,会得到不同的系统消耗和性能。
假设当前有n个待串行调度用户,每个用户可以使用A/B/C三种不同的调度策略,不同的策略会消耗不同的系统资源。请你根据如下规则进行用户调度,并返回总的消耗资源数。
规则:
相邻的用户不能使用相同的调度策略,例如,第1个用户使用了A策略,则第2个用户只能使用B或者C策略。
对单个用户而言,不同的调度策略对系统资源的消耗可以归一化后抽象为数值。例如,某用户分别使用A/B/C策略的系统消耗分别为15/8/17。
每个用户依次选择当前所能选择的对系统资源消耗最少的策略(局部最优),如果有多个满足要求的策略,选最后一个。
输入描述
第一行表示用户个数n
接下来每一行表示一个用户分别使用三个策略的系统消耗resA resB resC
输出描述
最优策略组合下的总的系统资源消耗数
用例
输入 | 3 |
输出 | 24 |
说明 | 1号用户使用B策略,2号用户使用C策略,3号用户使用B策略。系统资源消耗: 8 + 9 + 7 = 24。 |
调度策略资源消耗问题的最优解
核心解题思路
在调度多个用户时,每个用户可以选择A、B、C三种策略中的一种,但相邻用户不能使用相同策略。每个用户需选择当前允许的策略中消耗最小的选项,若最小值有多个则选最后的索引(即优先选C、B、A)。最终目标是计算所有用户的总资源消耗。
步骤分解
- 输入处理:读取用户数量和每个用户的三种策略消耗值。
- 逐个用户处理:根据前一个用户的策略确定当前可用策略,选择最小消耗的策略。
- 累加总消耗:将每个用户的策略消耗累加,得到最终结果。
详细实现步骤
1. 数据结构与输入处理
将每个用户的策略消耗存储为列表,例如用户输入 15 8 17
转换为 [15, 8, 17]
。
n = int(input())
users = []
for _ in range(n):
res = list(map(int, input().split()))
users.append(res)
2. 策略选择算法
初始化总消耗和前一策略索引,逐个用户确定可用策略并选择最优策略。
total = 0
prev_policy = -1 # 初始无前一策略
for i in range(n):
costs = users[i]
# 确定允许的策略范围(排除前一个策略)
allowed = [0, 1, 2] if prev_policy == -1 else [idx for idx in range(3) if idx != prev_policy]
# 找到允许策略中的最小值和对应索引
min_val = min(costs[idx] for idx in allowed)
candidates = [idx for idx in allowed if costs[idx] == min_val]
chosen = max(candidates) # 多个最小值时选最大索引
total += costs[chosen]
prev_policy = chosen # 更新前一策略
3. 复杂度分析
- 时间复杂度:O(n),每个用户遍历一次,策略选择为常数时间。
- 空间复杂度:O(n),存储每个用户的策略消耗。
关键知识点
1. 策略选择逻辑
- 排除相邻策略:根据前一用户的策略索引,限制当前用户的可用策略。
- 最小值选择:在允许的策略中找到消耗最小的值,若有并列选择索引最大的策略。
2. 贪心算法的适用性
虽然贪心算法不能保证全局最优,但根据题目规则(强制局部最优),必须采用此方式。
示例解析
输入用例
3
15 8 17
12 20 9
11 7 5
运行流程
- 用户1:允许所有策略,最小值8(索引1),总消耗8。
- 用户2:排除策略1,允许0和2,最小值9(索引2),总消耗17。
- 用户3:排除策略2,允许0和1,最小值7(索引1),总消耗24。
边界情况处理
1. 所有策略消耗相同
例如用户策略为 5 5 5
,选索引2(策略C)。
2. 连续用户最小值并列
例如用户策略为 5 5 3
,前一策略为0,则选索引2(策略C)。
总结
通过逐个用户贪心选择最优策略,并动态更新允许的策略范围,代码能够高效求解符合规则的资源消耗问题。该方法严格遵循题目要求,确保每一步选择局部最优,最终输出正确结果。