题解/算法 {1064. 小国王}

文章讨论了一种优化的动态规划方法来解决在n*n矩阵中放置K个棋子的问题,其中每个棋子周围8个位置不能有其他棋子。通过状态压缩和考虑每行作为一个元素,可以减少状态空间至最多100种合法的放法,从而降低时间复杂度。
摘要由CSDN通过智能技术生成

题解/算法 {1064. 小国王}

LINK: https://www.acwing.com/problem/content/1066/;

给定 n ∗ n n*n nn的矩阵, 如果一个位置上放棋子 则其相邻的8个位置上 不可以有棋子;
求一共放置 K K K个棋子的方案数;

用状态来表示, 每个位置用0/1来表示, 1表示该位置上放置棋子, 0表示该位置为空;

如果按照传统的遍历矩阵

0 1 2 3 4
5 6 7 8 9
a b c d e

比如, 当前枚举到c这个位置, 他的上个状态 即012...9ab这个子区域, c要判断的是b, 6, 7, 8这4个位置;
. 即对于一个区域, 我们需要记录他末尾的n的位置 他的状态用二进制表示1<<n就够了;
. 那么, Dp[ n*n][ 1<<n][ n*n]Dp[ i][ st][ k]表示: [0,1,...,i]这些元素 最后的n个位置 状态为n, 且总共[0,1,2,...,i]这些元素里 1的个数;
. 答案为Dp[ n*n -1][ 所有状态][ K]之和;
. 但这样的时间复杂度是1e9;

这种方式, 你是依次遍历的每个元素, 但是状态存储的是 n个元素, 即记录的是一行的状态;

其实, 既然你状态存储的是一行元素, 那么, 你可以直接遍历一行元素, 即把一整行元素 当成是一个元素;
. 把一整行元素 当成的一个元素, 这1个元素 有若干种放法 (原来1个元素 只有2种可能: 放/不放), 你可能认为他有1<<n个放法 其实不是的, 这里可以优化, 即只有不含连续的1 才可能是合法的放法, 这不多的 最多才100个;

一个元素 他的可能集合 和 放法, 不是相同的;
. 放法, 要看pre_st; 不同的pre_st 会决定cur_st的合法性;
. 而可能集合, 他与pre_st无关; 换句话说, 所有合法的cur_st (可用于状态转移的 就是合法的; 即存在一个pre_st 使得pre_st 结合 cur_st是合法的) 一定属于 可能集合; 但可能集合 不一定就是合法的;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值