求助,刚开始学状压DP要疯了
查看原帖
求助,刚开始学状压DP要疯了
223392
Belarus楼主2020/6/14 20:34

说一下我的思路:
fi,j,kf_{i,j,k} 表示第 ii 行状态为 jj 前面已经放了 kk 个国王。
fi,j,kvalid(j)=fi1,l,kcnt(l)valid(l),nd(j,l)\mathop{f_{i,j,k}}\limits_{valid(j)}=\sum \mathop{f_{i-1,l,k-cnt(l)}}\limits_{valid(l),nd(j,l)}
cnt(x)cnt(x) 表示二进制下 xx 有几个 1,valid(x)valid(x) 表示某一行的状态是合法的,nd(x,y)nd(x,y) 表示作为上下两行的状态 xxyy 并不冲突。
不知道哪里错了,样例也过不了。
求助qaq

#include<bits/stdc++.h>
using namespace std;
int n,K;
long long f[12][4096][12];
inline bool valid(int x){
	if(x&(x>>1)) return 0;
	if(x&(x<<1)) return 0;
	return 1;
}
inline bool nd(int x,int y){
	if(x&(y<<1)) return 0;
	if(x&y) return 0;
	if(x&(y>>1)) return 0;
	return 1;
}
inline int cnt(int x){
	int tmp=0;
	while(x){
		if(x&1) ++tmp;
		x>>=1;
	}
	return tmp;
}
int main(){
	cin>>n>>K;
	for(int j=0;j<(1<<n);++j)
	 if(cnt(j)<=K&&valid(j))
	  f[1][j][cnt(j)]=1;
	for(int i=2;i<=n;++i)
	 for(int j=0;j<(1<<n);++j)
	  if(valid(j))
	   for(int k=0;k<=K;++k)
	    for(int l=0;l<(1<<n);++l)
	     if(valid(l))
	      if(nd(j,l))
	       f[i][j][k]=f[i][j][k]+f[i-1][l][k-cnt(l)];
    long long ans=0;
    for(int j=0;j<(1<<n);++j)
     if(valid(j))
      ans=ans+f[n][j][K-cnt(j)];
    cout<<ans<<endl;
    return 0;
}
2020/6/14 20:34
加载中...