nyoj 492
令res[i][s1][k]表示第i行状态为s1,前i行摆放棋子的个数为k的方案个数;
res[i][s1][k]=∑res[i-1][s2][k-inum]; inum表示第i行摆放的棋子个数,s1,s2表示第i行和第i-1行的状态,两种状态能够相容。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define lld long long
lld res[11][1025][101];
int n,m;
int init(int j,int state,int inum,int b)
{
if(j>=n)
{
res[1][state][inum]=1;
return 0;
}
if(b==0)
{
init(j+1,(state<<1)+1,inum+1,1);
init(j+1,state<<1,inum,0);
}
if(b==1)
{
init(j+1,state<<1,inum,0);
}
return 0;
}
int dfs(int i,int j,int s1,int s2,int inum,int b)//b表示当前位置的摆放对后一列的影响
{
if(j>=n)
{
for(int l=0;l<=m;l++)
if(res[i-1][s2][l]) res[i][s1][l+inum]+=res[i-1][s2][l];
return 0;
}
if(b==0)
{
dfs(i,j+1,(s1<<1)+1,s2<<1,inum+1,1);
dfs(i,j+1,s1<<1,s2<<1,inum,0);
dfs(i,j+1,s1<<1,(s2<<1)+1,inum,1);
}
if(b==1)
{
dfs(i,j+1,s1<<1,s2<<1,inum,0);
}
return 0;
}
int main()
{
int i;
lld sum;
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(res,0,sizeof(res));
init(0,0,0,0);
for(i=2;i<=n;i++)
dfs(i,0,0,0,0,0);
sum=0;
for(i=0;i<(1<<n);i++)
sum+=res[n][i][m];
printf("%lld\n",sum);
}
return 0;
}
浙公网安备 33010602011771号