【状压dp】CDOJ1608 暑假集训

裸的状压的话,很显然……但有一个强大的优化。

就是在枚举决策的时候,固定第一个空位置。可以证明,这样状态数没有减少,但是降低了很多重复访问。

因为你在枚举的时候,总是可以划分为包含第一个空位置的3个位置;以及不包含第一个空位置的三个位置。这样固定先枚举前者,避免了重复。

还有一个优化是,没必要每次判断当前集合是否合法。

因为被更新到过的才是合法的,只需要一开始置成-1,不合法的状态一定不会被更新到。

#include
#include
#include
using namespace std;
int n,a[23][23][23],f[(1<<21)+10];
char c;
int ff;
inline void R(int &x){
    c=0;ff=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')ff=-1;
    for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0');
    x*=ff;
}
//inline bool check(int S){
//	int res=0;
//	for(int i=0;i>i)&1);
//	}
//	return res%3==0;
//}
int cans[23*23*23],o;
int main(){
	int x,y,z;
	R(n);
	for(int i=1;i<=n*(n-1)*(n-2)/6;++i){
		R(x); R(y); R(z);
		R(*(*(*(a+x-1)+y-1)+z-1));
	}
	memset(f,-1,sizeof(f));
	f[0]=0;
	for(int i=0;i<(1<>j)&1)){
				cans[++o]=j;
			}
		}
		for(int k=2;k<=o-1;++k){
			for(int l=k+1;l<=o;++l){
				f[i|(1<

转载于:https://www.cnblogs.com/autsky-jadek/p/6935079.html

你可能感兴趣的:(【状压dp】CDOJ1608 暑假集训)