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

    点此看题面

    大致题意:(N×N)的棋盘里面放(K)个国王,使他们互不攻击,共有多少种摆放方案(国王能攻击到它周围的8个格子)。

    状压(DP)

    一看到这道题我就想到了经典的八皇后问题,但是,这道题其实可以用状压(DP)来做。

    我们可以发现,影响该行国王摆放方法的只有上一行国王的摆放方式,因此,对于第(i)行,我们只需要知道第(i-1)行的国王的摆放方式即可。所以,我们可以用(f[i][j])来记录第(i)行,国王摆放方式为(j)的方案数即可(这里将摆放方式状态压缩成一个数)。

    注意要先预处理一下对于某一行的一种摆放方式是否合法且用了多少个国王。

    代码

    #include<bits/stdc++.h>
    #define LL long long
    #define N 9
    using namespace std;
    int n,m,could[(1<<N)+5],tot[(1<<N)+5];
    LL f[N+5][N*N+5][(1<<N)+5];
    inline char tc()
    {
    	static char ff[100000],*A=ff,*B=ff;
    	return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0;int f=1;char ch;
    	while(!isdigit(ch=tc())) f=ch^'-'?1:-1;
    	while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
    	x*=f;
    }
    inline void write(LL x)
    {
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10+'0');
    }
    inline void Start()//预处理每种摆放方案是否合法且用了几个国王
    {
    	register int i;
    	for(i=0;i<(1<<n);++i)
    	{
    		could[i]=1,tot[i]=0;
    		for(int num=i,lst=0;num;lst=num&1,num>>=1)
    		{
    			if(num&1)//若当前一位摆放了国王
    			{
    				if(lst) could[i]=0;//若前一位摆放了国王,则此方案不合法
    				++tot[i];//将国王的使用数量加1
    			}
    		}
    	}
    }
    inline int check(int x,int y)
    {
    	return !((x&y)||((x<<1)&y)||(x&(y<<1)));//比较两行的国王是否会攻击到对方
    }
    int main()
    {
    	register int i,j,k,l;
    	read(n),read(m),Start(),f[0][0][0]=1;
    	for(i=1;i<=n;++i)//核心代码
    		for(j=0;j<(1<<n);++j)
    			if(could[j]&&tot[j]<=m)
    				for(k=tot[j];k<=m;++k) 
    					for(l=0;l<(1<<n);++l)
    						if(could[l]&&check(j,l)) f[i][k][j]+=f[i-1][k-tot[j]][l];//进行转移,计算该行当前摆放方式的方案数
    	LL ans=0;
    	for(j=0;j<(1<<n);++j) ans+=f[n][m][j];//统计答案
    	return write(ans),0;
    }
    
  • 相关阅读:
    【转】各种图(流程图,思维导图,UML,拓扑图,ER图)简介
    【转】C缺陷和陷阱学习笔记
    【转】嵌入式C语言调试开关
    【转】循环冗余校验(CRC)算法入门引导
    idea非web项目打jar包运行
    centos7安装docker 部署springcloud
    centos7 unixodbc 连接mysql
    Mysql Communications link failure 终级解决办法
    https自签证书
    jenkins 打包 springboot
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1087.html
Copyright © 2011-2022 走看看