标签:
2005年省队选拔赛四川
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
方案数。
3 2
16
1 <=N <=9, 0 <= K <= N * N
题解:
用二进制表示状态,进行dp。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #define maxn 600 4 #include<algorithm> 5 6 using namespace std; 7 8 int n,m,b1[maxn],b2[maxn][maxn],sum[maxn]; 9 long long f[10][maxn][maxn]; 10 11 int main() 12 { 13 scanf("%d%d",&n,&m); 14 int s=(1<<n)-1; 15 for (int i=0;i<=s;i++) 16 if ((i&(i>>1))==0) 17 { 18 b1[i]=1; 19 int q=0; 20 for (int j=i;j;j=j>>1) 21 if (j&1) 22 q++; 23 sum[i]=q; 24 } 25 for (int i=0;i<=s;i++) 26 if (b1[i]) 27 for (int j=0;j<=s;j++) 28 if (b1[j]&&(i&j)==0&&((i<<1)&j)==0&&((i>>1)&j)==0) 29 b2[i][j]=1; 30 for (int i=0;i<=s;i++) 31 f[1][sum[i]][i]=1; 32 for (int i=1;i<n;i++) 33 for (int j=0;j<=s;j++) 34 if (b1[j]) 35 for (int k=0;k<=s;k++) 36 if (b1[k]&&b2[j][k]) 37 { 38 for (int q=sum[j];q+sum[k]<=m;q++) 39 f[i+1][sum[k]+q][k]+=f[i][q][j]; 40 } 41 long long ans=0; 42 for (int i=0;i<=s;i++) 43 ans+=f[n][m][i]; 44 printf("%lld\n",ans); 45 return 0; 46 }
标签:
原文地址:http://www.cnblogs.com/grhyxzc/p/5202615.html