E31 状态压缩DP 蒙德里安的梦想
视频链接:https://www.bilibili.com/video/BV1cv411b7EG/
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=12, M=1<<N; bool st[M]; //st[i]存储合并列的状态i是否合法 long long f[N][M]; //f[i][j]表示摆放第i列,状态为j时的方案数 int main(){ int n, m; while(cin>>n>>m, n||m){ // 预处理:判断合并列的状态i是否合法 // 合并列即两列状态合并之意,对应后面的st[j|k] // 如果合并列的某行是1表示横放,是0表示竖放 // 如果合并列不存在连续的奇数个0,即为合法状态 for(int i=0; i< 1<<n; i++){ st[i]=true; int cnt=0; //记录合并列中连续0的个数 for(int j=0; j<n; j++){ if(i>>j & 1){ //如果是1 if(cnt & 1){ //如果连续0的个数是奇数 st[i]=false; break; //记录i不合法 } } else cnt++; //如果是0,记录0的个数 } if(cnt & 1) st[i]=false; //处理高位0的个数 } memset(f, 0, sizeof f); f[0][0]=1; for(int i=1; i<=m; i++) //阶段:枚举列 for(int j=0; j < 1<<n; j++) //状态:枚举第i列的状态 for(int k=0; k < 1<<n; k++) //状态:枚举第i-1列的状态 if((j&k)==0 && st[j|k]) //两列状态兼容:不出现重叠的1,不出现连续的奇数个0 f[i][j] += f[i-1][k]; printf("%lld\n",f[m][0]); //第m列不横放即答案 } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!