http://poj.org/problem?id=2411
完全自己做的话 还真不行 能力还是不够呀
横着的两个小格 和竖着的第一个小格用 0 表示 竖着的第二个小格用 1表示
逐行更新 更新时用 DFS 最后一行要注意特判一下
代码及其注释:
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> #include<cmath> #include<stack> #include<algorithm> #define LL long long using namespace std; LL sum[15][1<<11]; //你懂得 LL Num; int n,m; void Dfs( int x, int i, int k, int j) //x 是第几位 用到k的最后一位比较 需要不断更新 j记录所有为取完的和 { if (x==m+1) { Num+=sum[i-1][j]; //累加 return ; } if (k%2==1) { Dfs(x+1,i,k/2,j); //此位只能找 0 } else { Dfs(x+1,i,k/2,j+ int ( pow (2,x-1))); //此位找 1 if (x!=m&&k/2%2!=1) { Dfs(x+2,i,k/2/2,j); //此位和下一位都找 0 } } } bool Can( int k) //特判一下最后一行 { int num=0; for ( int i=1;i<=m;++i) { if (k%2==1) { if (num%2==1) return false ; else num=0; } else { ++num; } k=k/2; } if (num%2==1) return false ; return true ; } int main() { while ( scanf ( "%d %d" ,&n,&m)!=EOF) { if (n==0&&m==0) break ; if (n%2&&m%2) { printf ( "0\n" ); continue ; } if (n==1||m==1) { printf ( "1\n" ); continue ; } memset (sum,0, sizeof (sum)); sum[1][0]=1; int M=1<<m; LL ans=0; for ( int i=2;i<=n;++i) { for ( int j=0;j<M;++j) { if (i==n&&Can(j)== false ) //最后一行 continue ; Num=0; Dfs(1,i,j,0); sum[i][j]+=Num; //累加 if (i==n) ans+=sum[i][j]; } } cout<<ans<<endl; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步