在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
标签:打表 limit amp ++i ret 不同 php www online
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
方案数。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 using namespace std; 6 #define LL long long 7 LL dp[10][85][1<<9],cnt[550]; 8 bool e[550][550],q[550]; 9 int N,M; 10 bool pd(int A,int B) 11 { 12 bool hurt[25]; memset(hurt,0,sizeof(hurt)); 13 for(int i=0;i<9;++i) 14 if(A&(1<<i)) hurt[i+1+5]=hurt[i-1+5]=hurt[i+5]=1; 15 for(int i=0;i<9;++i) 16 if( (B&(1<<i)) && hurt[i+5]) return 0; 17 return 1; 18 } 19 void pre() 20 { 21 for(int i=0;i<(1<<9);++i){ int ss=0; 22 for(int j=0;j<9;++j) if(i&(1<<j)) ss++; 23 cnt[i]=ss; 24 } 25 for(int i=0;i<(1<<9);++i){int ok=1; 26 for(int j=0;j<8;++j){ 27 if((i&(1<<j))&&(i&(1<<(j+1)))){ok=0;break;} 28 } 29 q[i]=ok; 30 } 31 for(int i=0;i<(1<<9);++i){ 32 for(int j=0;j<(1<<9);++j){ 33 if((!q[i])||(!q[j])) {e[i][j]=0;} 34 else { 35 if(pd(i,j)) {e[i][j]=1; } 36 } 37 } 38 } 39 } 40 int main() 41 { 42 pre(); 43 int i,j,k; 44 scanf("%d%d",&N,&M); 45 dp[0][0][0]=1; 46 for(i=1;i<=N;++i) 47 { 48 for(k=0;k<=M;++k) 49 { 50 for(int A=0;A<(1<<N);++A){ 51 for(int B=0;B<(1<<N);++B){ 52 if(e[A][B]&&k-cnt[B]>=0){ 53 dp[i][k][B]+=dp[i-1][k-cnt[B]][A]; 54 } 55 } 56 } 57 } 58 }LL ans=0; 59 for(i=0;i<(1<<N);++i) ans+=dp[N][M][i]; 60 printf("%lld\n",ans); 61 return 0; 62 }
标签:打表 limit amp ++i ret 不同 php www online
原文地址:http://www.cnblogs.com/zzqc/p/7258592.html