1. 程式人生 > >互不冒犯[狀壓DP]

互不冒犯[狀壓DP]

傳送門


#include<bits/stdc++.h>
#define N 10
#define M 1<<N
#define LL long long
using namespace std;
int n,k,cnt[M],sta[M],ret;
LL f[N][M][N*N],ans;
bool pd(int x,int y){
	return x&y || x&(y<<1) || x&(y>>1);
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<1<<n;i++){
		if(i&(i<<1) || i&(i>>1)) continue;
		int u=i; sta[++ret]=i ;while(u){
			if(u&1) cnt[ret]++;
			u>>=1;
		}
	}
	for(int i=1;i<=ret;i++) f[1][sta[i]][cnt[i]]=1;
	for(int i=2;i<=n;i++)
		for(int j=1;j<=ret;j++)
			for(int p=1;p<=ret;p++)
				if(!pd(sta[j],sta[p]))
					for(int q=0;q<=k;q++) f[i][sta[j]][cnt[j]+q] += f[i-1][sta[p]][q];
	for(int i=1;i<=ret;i++) ans+=f[n][sta[i]][k]; 
	printf("%lld",ans); return 0;
}