题目链接:HDU-4529
Sample Input
2
1
*.......
....*...
.......*
.....*..
..*.....
......*.
.*......
...*....
2
*.......
....*...
.......*
.....*..
..*.....
......*.
.*......
...*....
Sample Output
56
1409
思路:类似于炮兵阵地,当前这一行状态与前两行的状态有关系。枚举每行可能存在的状态。
AC:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
const int N=1e5+10;
char s[10][10];
int dp[10][1<<8][1<<8][12];//dp[i][j][k][l]表示第i层的状态为j,第i-1层状态为k,已经放了l个的数量;
int jis(int x)
{
int sum=0;
while(x)
{
if(x&1)
{
sum++;
}
x/=2;
}
return sum;
}
int judge(int i,int x)
{
int t=0;
int sum=0;
while(x)
{
if(x&1)
{
if(s[i][t]=='*')
{
sum=1;
break;
}
}
x/=2;
t++;
}
return sum;
}
int main()
{
int t;
int n;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=0; i<8; i++)
{
scanf("%s",s[i]);
}
for(int i=0; i<(1<<8); i++) //第一行
{
int val=jis(i);
if(!judge(0,i)&&val<=n)
{
dp[0][i][0][val]=1;
}
}
for(int i=1; i<8; i++)
{
for(int j=0; j<(1<<8); j++)
{
int val=jis(j);
if(!judge(i,j)&&val<=n)
{
for(int k=0; k<(1<<8); k++)
{
int vak=jis(k);
if((val+vak)<=n&&(j&(k>>2))==0&&(j&(k<<2))==0)
{
for(int u=0; u<(1<<8); u++)
{
int vau=jis(u);
if((val+vak+vau)<=n)
{
if((j&(u>>1))==0&&(j&(u<<1))==0&&(k&(u>>2))==0&&(k&(u<<2))==0)
{
for(int w=val; w<=n; w++)
{
dp[i][j][k][w]+=dp[i-1][k][u][w-val];
}
}
}
}
}
}
}
}
}
int ans=0;
for(int i=0; i<(1<<8); i++)
{
for(int j=0; j<(1<<8); j++)
{
ans+=dp[7][i][j][n];
}
}
printf("%d\n",ans);
}
return 0;
}