POJ 1321 - 棋盘问题..
简单的状态DP.由于审题不细..导致各种WA....
dp顺序至上而下...dp[x][y][z]代表到达 第x层..y代表二进制数..表示当前哪些列已经放好不能放了..z代表当前的棋子数...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<cmath> #define oo 1000000007 #define ll long long #define pi acos(-1.0) #define MAXN 10000005 using namespace std; char s[10][10]; int dp[10][550][10],n,k; bool putit(int a,int r) { int i,x; x=0; for (i=1;i<=n;i++) { if (a%2 && s[r][i]=='.') return false; if (a%2 && x) return false; if (a%2) x=1; a/=2; } return true; } bool ok(int a,int b) { while (a && b) { if (b%2 && a%2) return false; a/=2,b/=2; } return true; } int main() { int t,i,j,x,num,ans; while (~scanf("%d%d",&n,&k)) { if (n==-1 && k==-1) break; for (i=1;i<=n;i++) scanf("%s",s[i]+1); memset(dp,0,sizeof(dp)); dp[0][0][0]=1; for (t=1;t<=n;t++) for (i=0;i<(1<<n);i++) if (putit(i,t)) for (j=0;j<(1<<n);j++) if (ok(i,j)) { num=0; x=i; while (x) { num+=x%2; x/=2; } for (x=0;x<=n-num;x++) dp[t][i+j][x+num]+=dp[t-1][j][x]; } ans=0; for (i=0;i<(1<<n);i++) ans+=dp[n][i][k]; printf("%d\n",ans); } return 0; }