状压 2

状压

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

一般的处理步骤?

预处理

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

枚举

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

状态转移方程

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

例题

互不侵犯

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

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

炮兵阵地

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

疾病管理

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

进阶篇

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

先后限制最短路

状压计数

posted @   2K22  阅读(27)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示