其他分享
首页 > 其他分享> > 状压 2

状压 2

作者:互联网

状压

状态压缩,就是用一个整数代替DP中某种一般情况下需要以一维数组充当状态的状态
状压意义下的状态表示就是在\(P\)进制下将第\(i\)个元素的某种状态用整数第\(i\)位的\(j∈[0,P-1]\)表示出来
不同状态之间的转移需要用相应的位运算实现

一般的处理步骤?

预处理

首先预处理出各种可行的状态以及相应的权值
然后去各种状态转移

枚举

这就挺简单的了,将各种可行状态套状态转移方程直接算就行了

状态转移方程

状压的状态转移方程挺难适应的,主要是压缩里面的位运算
别的就阶段状态决策列出来状态转移方程就挺好整的了
注意好限制转移条件和可行决策的枚举就没别的了
似乎确实比优化直白但就是优化比状压难不知道为啥可能虚标了吧

例题

互不侵犯

定义\(kx[i]\)为第\(i\)个可行状态,\(cnt\)为可行状态总数
首先行内预处理\(kx\)数组
枚举从\(1\)到\(2^n-1\)
\(kx[i]\)的二进制表示下第\(j\)位为\(0\)表示无国王,\(1\)有国王
只考虑行内所以\(kx[i]\)每个\(1\)左右必须是\(0\)
这个可以通过左右移1解决:如果原数按位与上左右移1的数不为\(0\)不可行

棋盘问题一般以行号为阶段,所有的可行状态为状态
所以就以行号\(i\)为阶段,当前可行状态\(kx[j]\)为状态
决策?
根据题意,我们还需要为上一行的某个状态挑选当前的一个状态为决策,
不过这和设计相违背
反过来,设计上一行的一个状态为决策,就非常好整了
根据加法原理,我们知道:
状态转移方程:
\(f[i][kx[j][now]=\sum\limits^{k}_{now=sum[j]}f[i-1][kx[k]][now-sum[j]]\)
\(i\)是行号,\(kx[j]\)当前可行状态,\(kx[k]\)上行可行状态,额外维护的一些东西是对于数量限制
\(now\),当前的国王数,\(sum[j]\)当前可行状态下的国王数
转移条件:
\(kx[j] \and (kx[k]<<1) + kx[j] \and {kx[k]}+kx[j] \and (kx[k]>>1)==0\)
终值:
\(\sum\limits^{cnt}_{i=1}f[n][i][k]\)
初值:
\(f[0][1][0]=1\)

炮兵阵地

差不多,问最大值
预处理的还是行内所有可行状态以及个数
行号阶段,可行状态做状态,决策和上两行有关系,这里保存的决策上一行状态
首先预处理出地形上的矛盾:
可放为0,不可放为1
为节省空间把每行的地形状态作为限制条件
然后就是状态转移方程:
\(f[i][j][k1]=max(f[i][j][k1],f[i-1][k1][k2]+kx[j]);\)
\(i\)行号,\(j\)当前状态,\(k1,k2\)上一行和上两行状态
条件就直接与起来就行

疾病管理

直接状压
每头牛的表示就是每一位患病是1没病是0
然后就是直接枚举状态
全集就是当前状态,每头牛的表示必然是全集的子集
判断直接或一下就行
最后找到最大值就行

进阶篇

这里就是一些nb的计数原理或者限制先后最短路等等...
Continue

标签:状态,可行,sum,状压,kx,转移
来源: https://www.cnblogs.com/22222222STL/p/16271765.html