洛谷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;
}

  

原文地址:https://www.cnblogs.com/edmunds/p/13691653.html