数论-博弈 LeetCode-3283. 吃掉所有兵需要的最多移动次数 2473分

class Solution:
    def maxMoves(self, kx: int, ky: int, positions: List[List[int]]) -> int:
        positions.append([kx, ky])
        n = len(positions)

        @cache
        def knight_distance(start: Tuple[int, int], end: Tuple[int, int]) -> int:
            if start == end:
                return 0
                
            queue = deque([(start, 0)])
            visited = set([start])
            moves = [(1,2), (-1,2), (1,-2), (-1,-2), (2,1), (-2,1), (2,-1), (-2,-1)]
            
            while queue:
                (x, y), dist = queue.popleft()
                for dx, dy in moves:
                    nx, ny = x + dx, y + dy
                    if (nx, ny) == end:
                        return dist + 1
                    if 0 <= nx < 50 and 0 <= ny < 50 and (nx, ny) not in visited:
                        visited.add((nx, ny))
                        queue.append(((nx, ny), dist + 1))
            
            return -1

        pairwise_dist = {}
        for i, x in enumerate(positions):
            for j, y in enumerate(positions):
                pairwise_dist[(i, j)] = knight_distance(tuple(x), tuple(y))

        @cache
        def dp(cur_idx: int, mask: int, maximize: bool = True) -> int:
            if mask == 0:
                return 0
            
            best_val = -float('inf') if maximize else float('inf')
            for next_idx in range(n):
                if (1 << next_idx) & mask:  # pawn still alive
                    dist = pairwise_dist[(cur_idx, next_idx)]
                    val = dp(next_idx, mask ^ (1 << next_idx), not maximize) + dist
                    if maximize:
                        best_val = max(best_val, val)
                    else:
                        best_val = min(best_val, val)
            return best_val

        return dp(n-1, (1 << (n-1)) - 1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值