版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88928193
题目
https://www.luogu.org/problemnew/show/P1896
解题思路
设
表示第
行时,
行是第
个合法状态时,已经发了
个王的方案数。
判断是否合法:
(!(s[j]&s[k])&&!(s[j]&(s[k]>>1))&&!(s[j]&(s[k]<<1)))
bool ant=0;
while (x){
if ((x&1)&&ant) return 0;
if (x&1) ant=1; else ant=0;
x>>=1;
}
return 1;
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,x,y) for (register int i=x;i<=y;i++)
using namespace std;
typedef long long ll;
const int N=10,MAXN=(1<<9);
int n,m,s[MAXN],t[N],tot,a[MAXN];
ll ans,f[N][MAXN][N*N];
bool check(int x){
bool ant=0;
while (x){
if ((x&1)&&ant) return 0;
if (x&1) ant=1; else ant=0;
x>>=1;
}
return 1;
}
int lowbit(int x){
int ant=0;
while (x){
ant+=(x&1);
x>>=1;
}
return ant;
}
int main(){
scanf("%d%d",&n,&m); int M=1<<n;
rep(i,0,M-1) if (check(i)) s[++tot]=i,a[tot]=lowbit(i),f[1][tot][a[tot]]=1;
rep(i,2,n) rep(j,1,tot) rep(k,1,tot)
if (!(s[j]&s[k])&&!(s[j]&(s[k]>>1))&&!(s[j]&(s[k]<<1)))
rep(l,0,m-a[j]) f[i][j][l+a[j]]+=f[i-1][k][l];
rep(i,1,tot) ans+=f[n][i][m];
printf("%lld",ans);
}