题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法。矩形大小最大 12*12.
压缩状态DP大多有一个可行的state的范围,先求出这个state范围,对接下来的解题非常有帮助!
注意特判 N==1 的情况。
#include <iostream> #include <cmath> #include <cstring> #include <vector> using namespace std; vector<int> t; // the current map vector<int> s; // possible state int MOD = 100000000; int dp[15][1<<15]; int main() { //freopen("1.txt","r",stdin); int M,N; while(cin>>M>>N) { s.clear(); t.clear(); for(int tag=0; tag< (1<<N); tag++) { for(int k=0; k<N-1; k++) { if((tag &(1<<k)) && (tag &(1<<(k+1)))) break; if( k== N-2) s.push_back(tag); } } if(N == 1) {s.push_back(0); s.push_back(1);} for(int i=0; i<M; i++) { int x = 0; for(int j=0; j<N; j++) { int tag; cin>>tag; x += tag<<(N - j -1); } t.push_back(x); } memset(dp, 0, sizeof(dp)); for(int i=0; i<s.size(); i++) { if((s[i] | t[0]) ^ t[0]) continue; dp[0][s[i]] = 1; } for(int i=1; i< M; i++) // row i { for(int j=0; j<s.size(); j++) { if((s[j] | t[i]) ^ t[i]) continue; //cout<<"Possible" <<s[j]<<endl; // cur state is s[j], pre is s[k]; for(int k=0; k<s.size(); k++) { if(s[j] & s[k]) continue; dp[i][s[j]] += dp[i-1][s[k]]; dp[i][s[j]] %= MOD; } } } int ret = 0; for(int i=0; i<s.size(); i++) { ret += dp[M-1][s[i]]; ret %= MOD; } cout<<ret<<endl; } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)