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;
}


 

 

posted @ 2013-07-14 22:18  坚固66  阅读(105)  评论(0编辑  收藏  举报