zoukankan      html  css  js  c++  java
  • BZOJ1087 [SCOI2005]互不侵犯King 状压DP

    参考自

    9*9的棋盘问能放多少k个国王的放置方法数。。

    这种预处理状态间能否转移的做法还是第一次见(naive

    不过用位运算判转移可能性在当状态大存不下没法预处理的时候也不算慢。。?

    左右移位判重合挺巧妙的。。。

    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    #include<stack>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define pb push_back
    #define mem(a) memset(a,0,sizeof a)
    #define FOR(a) for(int i=1;i<=a;i++)
    #define sqr(a) (a)*(a)
    
    const int maxn=6e2+5;	//1<<9
    
    int n,k;
    ll ans;
    bool s[maxn],G[maxn][maxn];	//判状态是否合法,判能否邻行
    int num[maxn];				//状态i有多少个1位
    ll f[10][100][600];			//前i行放j个1,第i行状态为k
    int sum;					//sum种状态
    
    void pre_s(){
    	for(int i=0;i<sum;i++){
    		if((i&(i<<1))==0){	//本行没相邻
    			s[i]=true;
    			int t=i,cnt=0;
    			while(t){
    				cnt+=(t&1);
    				t>>=1;
    			}
    			num[i]=cnt;
    			f[1][cnt][i]=1;
    		}
    	}
    }
    void pre_G(){
    	for(int i=0;i<sum;i++){
    		if(!s[i])continue;
    		for(int j=0;j<sum;j++){
    		 	if(!s[j])continue;
    			if( (!(i&j)) && (!((i<<1)&j)) && (!((i>>1)&j)) )G[i][j]=true;
    		}
    	}
    }
    
    void dp(){
    	for(int i=2;i<=n;i++)
    		for(int j=0;j<=k;j++)
    			for(int now=0;now<sum;now++){
    				if(!s[now])continue;
    				if(num[now]>j)continue;
    				for(int fr=0;fr<sum;fr++){
    					if(!s[fr])continue;
    					if(!G[fr][now])continue;
    					if(num[fr]+num[now]>j)continue;
    					f[i][j][now]+=f[i-1][j-num[now]][fr];
    				}
    			}
    }
    
    int main(){
    	scanf("%d%d",&n,&k);
    	sum=1<<n;
    	pre_s();
    	pre_G();
    	dp();
    	for(int i=0;i<sum;i++){
    		if(!s[i])continue;
    		ans+=f[n][k][i];
    	}
    	printf("%lld
    ",ans);
    }


  • 相关阅读:
    第四次
    jsp
    2021.3.4
    第八次作业
    第七次作业
    第六周作业
    第五周作业
    第四周
    第四次jsp作业
    第二次作业
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611222.html
Copyright © 2011-2022 走看看