luogu P1896 [SCOI2005]互不侵犯 状态压缩dp

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=15,K=110,M=1<<10;
ll f[N][K][M];
int n,m;
int cnt[M];
vector<int>head[M];
vector<int>state;
bool check(int x)
{
	for(int i=0; i+1<n; i++)
		if((x>>i&1) && (x>>i+1&1))
			return false;
	return true;
}
int count(int x)
{
	int ans=0;
	for(int i=0; i<n; i++)
		ans+=x>>i&1;
	return ans;
}
int main()
{
	cin>>n>>m;
	for(int i=0; i< 1<<n; i++)
		if(check(i))
		{
			state.push_back(i);
			cnt[i]=count(i);
		}
	for(int i=0; i<state.size(); i++)
		for(int j=0; j<state.size(); j++)
		{
			int a1=state[i],b1=state[j];
			if( (a1&b1)==0 && check(a1|b1))
				head[i].push_back(j);
		}
	f[0][0][0]=1;
	for(int i=1; i<=n+1; i++)
		for(int j=0; j<=m; j++)
			for(int a=0; a<state.size(); a++)
				for(auto b : head[a])
				{
					int c=cnt[ state[a] ];
					if(j>=c)
						f[i][j][a]+=f[i-1][j-c][b];
				}
	cout<<f[n+1][m][0]<<endl;
	return 0;
}

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12887958.html