[SGU223]Little Kings(状压DP)

随便DP一下

Code

#include <cstdio>
#include <algorithm>
#define N 12
#define ll long long
using namespace std;

int sta[150],cnt[150],tp,n,k,bit[N];
ll dp[N][N*N][150],Ans;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

void Init(){
	bit[0]=1;for(int i=1;i<=10;++i)bit[i]=bit[i-1]<<1;
	n=read(),k=read();
	for(int i=0;i<bit[n];++i){
		if((i&(i<<1))||(i&(i>>1)))continue;
		sta[++tp]=i;
	}
	for(int i=1;i<=tp;++i)for(int x=sta[i];x;x&=(x-1),++cnt[i]);
	for(int i=1;i<=tp;++i)dp[1][cnt[i]][i]=1;
}

int main(){
	Init();int nn=n*n;
	for(int i=1;i<n;++i)
		for(int j=0;j<=nn;++j)
			for(int k=1;k<=tp;++k){
				if(!dp[i][j][k])continue;
				for(int x=1;x<=tp;++x){
					if((sta[x]&sta[k])||((sta[x]<<1)&sta[k])||((sta[x]>>1)&sta[k]))continue;
					dp[i+1][j+cnt[x]][x]+=dp[i][j][k];
				}
			}
	for(int i=1;i<=tp;++i)Ans+=dp[n][k][i];
	printf("%lld\n",Ans);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/void-f/p/9379618.html