当前位置: 首页 > news >正文

【笔记】状压 DP

Luogu P1896 [SCOI2005] 互不侵犯

因为一行的状态只有放与不放国王,所以可以用 \(0\)\(1\) 表示,然后就可以把一行的状态压缩成一个 \(9\) 位二进制数表示,状态个数为 \(2^9\)。随后定义状态 \(f(i,j,s)\) 表示前 \(i\) 行放 \(j\) 个国王,最后一行状态为 \(s\) 的方案数。先 DFS 求出一行的所有状态,然后暴力枚举相邻两行的状态,判断合法性,如果合法就进行状态转移:\(f(i,j,s)=f(i-1,j-sta_{cnt1},sit_{cnt2})\),其中 \(sta\) 存储的是每个状态摆放的国王数量,\(sit\) 存储的是每个状态,\(cnt1\)\(cnt2\) 分别记录了第 \(i-1\) 行和第 \(i\) 行的状态编号。

最后统计答案,即为把所有摆 \(i\) 行、\(k\) 个国王的方案数累加。方案数和累加结果记得开 long long

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
int n,m,cnt;
long long ans;
int king[2010],state[2010],f[10][110][2010];
void dfs(int s,int cur,int num){if(cur>=n){state[++cnt]=num;king[cnt]=s;return ;}else{dfs(s,cur+1,num);dfs(s+(1<<cur),cur+2,num+1);}
}
bool check(int a,int b){if((king[a]<<1)&king[b]) return 0;if((king[a]>>1)&king[b]) return 0;if((king[a])&king[b]) return 0;return 1;
}
signed main(){scanf("%lld%lld",&n,&m);dfs(0,0,0);for(int i=1;i<=cnt;i++){f[1][state[i]][i]=1;}for(int i=2;i<=n;i++){for(int j=1;j<=cnt;j++){for(int k=1;k<=cnt;k++){if(!check(j,k)) continue;for(int l=state[j];l<=m;l++){f[i][l][j]+=f[i-1][l-state[j]][k];}}}}for(int i=1;i<=cnt;i++) ans+=f[n][m][i];cout<<ans;return 0;
} 

至于时间复杂度,比较难估计,大概是 \(O(4^n \times nk)\)。总之 \(n\) 很小,跑得很快(实测洛谷数据 57ms,loj 还没有测)。

空间是三维的,要注意不要开太大。

Luogu P5911 [POI2004] PRZ

这个题是一道典型的枚举子集。把集合状压并预处理出每个子集所需要的最大时间 \(t_i\) 和重量 \(w_i\),枚举所有人构成的集合 \(S\) 中的子集 \(i\)\(i\) 的子集 \(j\),那么:

\[dp_i=\min(dp_i,t_i+dp_{i \oplus j})(w_j \le W) \]

这里枚举子集 \(j\) 不能先枚举集合再判断是否为 \(i\) 的子集,这样时间复杂度会来到 \(O(4^n)\),过不了。应当使用 子集枚举,时间复杂度来到 \(O(3^n)\)

http://www.jsqmd.com/news/79237/

相关文章:

  • 基于java的SpringBoot/SSM+Vue+uniapp的篮球管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 【题解】Luogu P5905【模板】全源最短路(Johnson)
  • 基于SpringBoot的宠物识别小程序的设计与实现毕业设计项目源码
  • 基于SpringBoot的传统服饰订制系统毕业设计项目源码
  • 美团原生AI编辑器
  • 基于SpringBoot的大学生体测数据管理系统毕业设计项目源码
  • P3258 [JLOI2014] 松鼠的新家
  • K8S 中使用 YAML 安装 ECK
  • 如何更详细地应用AI提升学习效率?——大学生实战指南
  • 2025 最新租房/找房平台 TOP4 评测!数智化赋能 + 全维服务权威榜单发布,重构居家生活服务新生态 - 全局中转站
  • 当电机开始“唱歌“:NVH工程师的降噪日常
  • 在写小故事
  • Linux 中如何将文本中连续的字段转换成一个字段显示
  • 光伏板太阳能充电MATLAB仿真探索
  • 26、端口敲门与单包授权:网络安全认证技术对比
  • QtCreator IDE中向项目添加ui文件并绑定类
  • PI + 重复控制的并联型APF有源电力滤波器仿真探索
  • 20、深入理解Snort规则选项与iptables数据包过滤
  • 教程 29 - 从磁盘加载纹理
  • 从自动化到智能化,构建企业级Workflow Agent系统实战指南
  • 基于SpringBoot的大学生在线考试平台的设计与实现毕业设计项目源码
  • 003-RSA魔改:一号店
  • 创维LB2004_瑞芯微RK3566_2G+32G_删除移动定制_安卓11_原生桌面_线刷固件包-方法4
  • Jeecg AI开源平台:零门槛构建AI应用的完整指南
  • 与AI共舞:当代大学生如何在智能时代重塑学习与成长
  • RPA在企业微信桌面端的元素识别:基于坐标与基于属性的优劣对比
  • 详细介绍:【分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
  • 【Java避坑】为什么我的 String a == b 返回 false?一文搞懂 Java 中的 == 与 equals
  • 教程 30 - 纹理系统
  • 【题解】Luogu P1310 [NOIP 2011 普及组] 表达式的值