题目简述:
给出一个n*n的国际象棋棋盘,上面能放k个互补攻击的象有多少种方法(在对角线的话会相互攻击)
分析:
#include<bits/stdc++.h>
using namespace std;
const int N=8;
int b[N+1],w[N+1],rb[N+1][65],rw[N+1][65];
void init(int n){
memset(b,0,sizeof b);
memset(w,0,sizeof w);
//初始化黑白棋盘。
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if((i+j)&1) w[i+j>>1]++;
else b[i+j>>1]++;
}
}
}
//递推公式求解
void solve(int n,int k,int c[],int r[][65]){
for(int i=0;i<=n;i++){
r[i][0]=1;
}
for(int j=1;j<=k;j++){
r[0][j]=0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=c[i];j++){
r[i][j]=r[i-1][j]+r[i-1][j-1]*(c[i]-j+1);
}
}
}
int main(){
int n,k,ans;
while(scanf("%d%d",&n,&k)!=EOF){
if(n==0&&k==0) break;
init(n);
sort(b+1,b+1+n);
sort(w+1,w+n);
solve(n,k,b,rb);
solve(n-1,k,w,rw);
ans=0;
for(int i=0;i<=k;i++){
ans+=rb[n][i]*rw[n-1][k-i];
}
printf("%d\n",ans);
}
return 0;
}