洛谷P1896 互不侵犯
题目链接:https://www.luogu.com.cn/problem/P1896
题意:nxn棋盘里摆k个国王,如果一个格子摆了,那么周围的8个都不能摆。求能放k个国王的方案数
设f[i][s][t]表示前i行,第i行的状态为s,此时放了k个国王的方案数。则有
f[i][s][t]=Σf[i-1][s'][t-count(s')],和poj3254类似,s和s'本身要是合法的状态,且s和s'要兼容
最后答案为Σf[n][s][t]
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k,s,s2,i,j,t;
ll f[12][(1<<12)][100];
/*f[i][s][t]:前i行,第i行状态为s,放置了t个的方案数*/
int main(){
cin>>n>>k;
f[0][0][0]=1; //*
for (t=0;t<=k;t++) //*从0枚举
for (i=1;i<=n;i++)
for (s=0;s<(1<<n);s++){
ll num=0; ll b=0;
for (j=0;j<n;j++){
if (s&(1<<j)) num++;
if (s&(1<<j)&&s&(1<<(j+1))) {
b=1; break;
}
}
if (b) continue;
for (s2=0;s2<(1<<n);s2++)
if ((s&s2)==0&&(s&(s2<<1))==0&&(s&(s2>>1))==0) //*
if (t>=num) f[i][s][t]+=f[i-1][s2][t-num];
}
ll ans=0;
for (s=0;s<(1<<n);s++) ans+=f[n][s][k]; //*
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号