简单的状态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;
}