题目:http://poj.org/problem?id=2411
状压dp。注意一下代码中标记的地方。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,lm; long long d[15][1<<12],ans; bool list[1<<12]; void pre() { memset(list,0,sizeof list); for(int i=0;i<lm;i++) { bool flag=0; int k=0,u=i;////// while(++k<=m) { if(!(u&1)) { int ct=1; while(((u>>1)&1)==0&&k+1<=m) { k++;u>>=1;ct++; } if(ct%2) { flag=1;break; } } u>>=1;////// } if(!flag)list[i]=1; } } int main() { while(1) { scanf("%d%d",&n,&m); if(!n&&!m)return 0; if(n==1) { printf("%d ",!(m%2)); continue; } lm=1<<m; pre(); memset(d,0,sizeof d); for(int i=0;i<lm;i++) if(list[i]) d[1][i]=1; for(int i=2;i<n;i++) for(int j=0;j<lm;j++) for(int k=0;k<lm;k++) if(!(k&j)&&list[k|j]) d[i][j]+=d[i-1][k]; ans=0; for(int k=0;k<lm;k++) if(list[k])ans+=d[n-1][k];//////最后一行只能全0! printf("%lld ",ans); } }