[SCOI2005]互不侵犯

洛谷题目链接

LOJ题目链接


状压dp。

code:

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int lowbit(int x) {return x&-x;}
int getk(int n)
{
	int ans=0;
	while(n)
	{
		++ans;
		n-=lowbit(n);
	}
	return ans;
}
int n,st[1000],tot=0,num[1000];
ll dp[20][1000][100];
void init()
{
	int all_state=(1<<n)-1;
	for(int i=0;i<=all_state;i++)
	{
		if(!(i&(i<<1)))
		{
			st[++tot]=i;
			num[tot]=getk(i);
		}
	}
}
int main()
{
	int K;
	scanf("%d %d",&n,&K);
	init();
//printf("tot:%d\n",tot);	
	for(int i=1;i<=tot;i++) dp[1][st[i]][num[i]]=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=tot;j++)
		{
			for(int k=1;k<=tot;k++)
			{
				if(st[j]&st[k]) continue;
				if((st[j]<<1)&st[k]) continue;
				if(st[j]&(st[k]<<1)) continue;
//				puts("kkksc03");
				for(int s=1;s<=K;s++) dp[i][st[j]][num[j]+s]+=dp[i-1][st[k]][s];
			}
		}
	}
	ll ans=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=tot;j++)
			ans+=dp[i][st[j]][K];
	printf("%lld",ans);
	return 0;
}
posted @ 2020-03-03 15:35  zzt1208  阅读(132)  评论(0编辑  收藏  举报