华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)A
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
游戏里面,队伍通过匹配实力相近的对手进行对战。但是如果匹配的队伍实例相差太大,对于双方游戏体验都不会太好。
给定n个队伍的实力值,对其进行两两实力匹配,两支队伍实例差距在允许的最大差距d内,则可以匹配。
要求在匹配队伍最多的情况下,匹配出的各组实力差距的总和最小。
输入描述
第一行,n,d。队伍个数n。允许的最大实力差距d。(2<=n<=50,0<=d<=100)。
第二行,n个队伍的实力值,空格分割。(0<=各队伍实力值<=100)。
输出描述
匹配后,各组对战的实力差值的总和。若没有队伍可以四配,则输出-1。
示例1
输入:
6 30
81 87 47 59 81 18
输出:
57
说明:
18与47配对,实力差距29;
59与81配对,实力差距22;
81与87配对,实力差距6。
总实力差距29+22+6=57。
示例2
输入:
6 20
81 87 47 59 81 18
输出:
12
说明:
最多能匹配成功4支队伍。
47与59配对,实力差距12;
81与81配对,实力差距0。
总实力差距12+0=12。
示例3
输入:
4 10
40 51 62 73
输出:
-1
说明:
实力差距都在10以上,没有队伍可以匹配成功。
题解
这道题目属于贪心算法(Greedy Algorithm)和动态规划(Dynamic Programming)的结合。我们需要在满足匹配条件的情况下,最大化匹配数量并最小化实力差距总和。类似的问题在力扣上通常归类为区间调度或二分图匹配问题。
解题思路
- 排序:首先将队伍的实力值排序,以便后续匹配时能快速找到满足条件的队伍。
- 贪心匹配:从最小的实力值开始,尝试与最近的满足条件的队伍匹配。这样可以保证在匹配数量最多的情况下,实力差距总和最小。
- 动态规划:使用递归或记忆化搜索来记录已匹配的队伍,避免重复匹配,并确保在每一步选择最优解。
Python
from functools import cache
def main():
n, d = map(int, input().split())
power = list(map(int, input().split()))
power.sort() # 升序排序
@cache
def dfs(i):
if i >= n:
return (0, 0)
# 不选当前队伍
cnt1, diff1 = dfs(i + 1)
# 选当前队伍和下一个满足条件的队伍
cnt2, diff2 = 0, 0
if i + 1 < n and power[i + 1] - power[i] <= d:
cnt2, diff2 = dfs(i + 2)
cnt2 += 1
diff2 += power[i + 1] - power[i]
# 优先匹配数多的方案,其次选总差值小的
if cnt2 > cnt1:
return (cnt2, diff2)
elif cnt1 > cnt2:
return (cnt1, diff1)
else:
return (cnt1, min(diff1, diff2))
total_cnt, total_diff = dfs(0)
print(total_diff if total_cnt > 0 else -1)
if __name__ == "__main__":
main()
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏