#-*-coding: GBK -*- import math import heapq def boss_fight(B, PlayerSkills): n = len(B) m = len(PlayerSkills) if n == 0: return [] # 计算最大平均伤害用于启发式函数 max_avg = 0.0 for a, b in PlayerSkills: if b + 1 > 0: avg = a / (b + 1) if avg > max_avg: max_avg = avg # 如果所有技能伤害为0,则无法击败BOSS if max_avg == 0: return None # 初始状态:boss索引0,血量B[0],冷却全0,回合数0,路径空 start_cooldown = tuple([0] * m) total_remaining = sum(B) #f_value = 当前回合数 + 估计剩余回合数 f_value = math.ceil(total_remaining / max_avg) if max_avg > 0 else total_remaining # 初始化优先队列 (f_value, round_count, boss_idx, boss_rem, cooldown, path) queue = [(f_value, 0, 0, B[0], start_cooldown, [])] # 记录访问过的状态(boss_idx, boss_rem, cooldown) -> 最小回合数 visited = {} visited[(0, B[0], start_cooldown)] = 0 all_path = [] # 优先队列按f_value排序 while queue: # 优先扩展f_value最小的状态(最有希望的状态) f_value, round_count, boss_idx, boss_rem, cooldown, path = heapq.heappop(queue) state_key = (boss_idx, boss_rem, cooldown) # 状态检查:如果已有更好状态,跳过当前状态 if visited.get(state_key, float('inf')) < round_count: continue # 所有BOSS已击败 if boss_idx >= n: return path # 等待操作:所有冷却时间减1,回合数+1,路径添加-1 new_cooldown_list = [max(0, c - 1) for c in cooldown] new_cooldown = tuple(new_cooldown_list) new_round = round_count + 1 new_state_key = (boss_idx, boss_rem, new_cooldown) # 若新状态更优,则加入队列 if new_state_key not in visited or visited[new_state_key] > new_round: visited[new_state_key] = new_round total_remaining = boss_rem + sum(B[boss_idx+1:]) estimate_rounds = math.ceil(total_remaining / max_avg) if max_avg > 0 else 0 new_f = new_round + estimate_rounds new_path = path + [-1] heapq.heappush(queue, (new_f, new_round, boss_idx, boss_rem, new_cooldown, new_path)) # 使用技能 for skill_idx, (a, b) in enumerate(PlayerSkills): if cooldown[skill_idx] != 0: # 技能不可用 continue new_boss_idx = boss_idx new_boss_rem = boss_rem - a # 击败当前BOSS if new_boss_rem <= 0: new_boss_idx += 1 all_path.append(new_path) new_path = [] if new_boss_idx < n: new_boss_rem = B[new_boss_idx] # 切换至下一个BOSS else: new_boss_rem = 0 # 所有BOSS已击败 # 更新冷却时间 new_cooldown_list = [max(0, c - 1) for c in cooldown] new_cooldown_list[skill_idx] = b # 重置当前技能冷却时间 new_cooldown = tuple(new_cooldown_list) new_round = round_count + 1 new_path = path + [skill_idx] # 所有BOSS已击败,返回路径 if new_boss_idx >= n: return all_path new_state_key = (new_boss_idx, new_boss_rem, new_cooldown) # 若新状态更优,则加入队列 if new_state_key not in visited or visited[new_state_key] > new_round: visited[new_state_key] = new_round total_remaining = new_boss_rem + sum(B[new_boss_idx+1:]) estimate_rounds = math.ceil(total_remaining / max_avg) if max_avg > 0 else 0 new_f = new_round + estimate_rounds heapq.heappush(queue, (new_f, new_round, new_boss_idx, new_boss_rem, new_cooldown, new_path)) return None # 无解 if __name__ == '__main__': B = [10, 20, 30, 40, 50] PlayerSkills = [(5, 2), (8, 3), (3, 1)] ans = boss_fight(B, PlayerSkills) for i in ans: print(i)