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

    Description

    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

    Input

    只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

    Output

    所得的方案数

    很明显(N leq 9)状压DP啊 qwq.

    这里有限制,我们只能放(K)个国王,并且如果一个格子有国王,其周围八个格子都不能放.

    设状态(f[i][j][k])代表前(i)行中第(i)行为(j)状态下共放了(k)个国王的方案数.

    状态转移的话,我们当前行显然已经放了国王.

    因此,转移可以很容易想到.

    [f[i][j][l+calc(j)]+=f[i-1][k][l] ]

    其中(l)为枚举的上一行所放的国王的个数,(k)为枚举的上一行的状态,(calc(j))为计算(j)状态下有多少个国王被放置.

    判断合法与否的话,只需要判断一下当前(j)状态与(k)状态(&)起来是否为零。

    如何判断状态合法

    判断是否(j)状态的某一位置右上方有无国王.

    [(j>>1)&k==0 ]

    同理左上方

    [(j<<1)&k==0 ]

    正上方

    [j&k==0 ]

    这几个方向是相对而言的.且我们从第(1)行到第(n)行放置的话,每次判断是否合法达到了判断6个方向的效果.

    判断左右两侧当然是最简单的了

    [j&(j>>1)==0 && j&(j<<1)==0 ]

    代码

    #include<cstdio>
    #define int long long
    #define R register
    using namespace std;
    int n,m,f[10][2048][108];
    int lim,ans;
    inline bool ok(int i)
    {
    	return ((i&(i<<1))==0 and (i&(i>>1))==0);
    }//相邻方向. 
    inline int calc(int x)
    {
    	int res=0;
    	for(R int i=0;(1<<i)<=x;i++)
    		res+=(bool)(x&(1<<i));
    	return res;
    }
    signed main()
    {
    	scanf("%lld%lld",&n,&m);
    	f[0][0][0]=1;
    	lim=(1<<n)-1;
    	for(R int i=1;i<=n;i++)
    	{
    		for(R int j=0;j<=lim;j++)
    		{
    			if(!ok(j))continue;
    			for(R int k=0;k<=lim;k++)
    			{
    				if(!ok(k))continue;
    				if((j&k)==0 and ((j<<1)&k)==0 and ((j>>1)&k)==0)
    				{
    					R int now=calc(j);
    					for(R int l=0;l<=m;l++)
    						f[i][j][l+now]+=f[i-1][k][l];
    				}
    			}
    		}
    	}
    	for(R int i=0;i<=lim;i++)
    		ans+=f[n][i][m];
    	printf("%lld
    ",ans);
    }
    

    可以滚动数组滚掉第(1)维,切在枚举(l)的时候,第三维可能会超内存,因此要开大一点.当然也可以判断一下(l+now leq m)

  • 相关阅读:
    一些关于HDFS的基本知识
    WordPress使用子主题继承和修改主题
    IQueryable、IQueryProvider接口详解
    FM并发编程练习:改写苏飞的C#多线程网站压力测试程序
    利用Webkit抓取动态网页和链接
    HTTP协议之代理
    PortalBasic Java Web 应用开发框架 v3.0.1 即将发布
    算法导论1.排序算法
    CSS题目 子元素决定父元素的大小
    使用solrj和EasyNet.Solr进行原子更新
  • 原文地址:https://www.cnblogs.com/-guz/p/9794102.html
Copyright © 2011-2022 走看看