这个题目非常赞! 给定一个矩形,要求用1*2 的格子进行覆盖,有多少种覆盖方法呢?
dp[i][j] 当状态为j,且第i行已经完全铺满的情况下的种类数有多少种?j中1表示占了,0表示没有被占。
很显然,当每行被放了之后,有一些状态是不可能的,我们这里用1 表示竖着放,0表示横着放。 所以两个0 要相邻,这是程序中的s。
我们每一状态转移,枚举每一个可能的状态,我们希望dp[i][j] 中的j呈现出s[k] 的状态,依次来进行状态转移。
#include <iostream> #include <vector> #include <cstring> using namespace std; vector<int> s; // possible state long long dp[13][1<<12]; // dp[i][j] the number of (row i state j) int main() { //freopen("1.txt","r",stdin); int M,N; while(cin>>M>>N && M!=0 && N!=0) { s.clear(); if(M*N%2) {cout<<0<<endl; continue;} memset(dp,0,sizeof(dp)); // 0-0 pair for(int tag = 0; tag < (1<<N); tag++) { for(int i=0; i<N; ) { if(tag & (1<<i)) i++; else { if( i+1< N && !(tag&(1<<(i+1)))) i+=2; else break; } if(i== N) s.push_back(tag); } } for(int i=0; i<s.size(); i++) dp[0][s[i]] = 1; for(int step = 1; step< M; step++) { for(int tag = 0; tag < (1<<N); tag++) { for(int i=0; i<s.size(); i++) { if((tag & s[i]) != tag) continue; dp[step][tag^ s[i]] += dp[step-1][tag]; } } } cout<<dp[M-1][0]<<endl; } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步