zoukankan      html  css  js  c++  java
  • [SCOI2005]互不侵犯

    [SCOI2005]互不侵犯

    状压DP练习题

    我们先审个题:

      首先注意这道题的数据范围

    (1leq N leq 9 , 0 leq Kleq N^2)

    是不是真的很小啊,所以我们考虑用状压DP或爆搜的办法解。

    解法:

      这道题求方案数,那么可以很自然的想到用dp或者搜索,然而对于本题而言,搜索需要记录的信息和状态太多,会T到天上去,所以只有采用状压DP来解决。
       注意到n非常小,而且状态需要记录的信息非常多,所以考虑状态压缩dp。在这道题里,当前行的状态和上一行的状态有着密切联系,而且答案和k有关,所以我们设计状态f[i][j][k]为前i行已经放了j个国王并且第i行的状态为k(二进制)的方案数,那么(f[i][j][k] = sum f[i - 1][j - num[k]][l]),其中num数组记录着一行为状态k的放的国王的数目,l为上一行符合要求的状态.
    现在的问题就是如何判断状态i是否符合要求,这不仅与i本身有关,还和它上一行的状态j有关,利用左移,右移,&就可以判断了,它的原理是什么呢?我们把每个状态抽象成1个二进制数,它的第i位表示第i列放不放国王,利用&的性质,可以判断上下两行是否冲突,那么如何判断当前行是否冲突呢?将i左移1位再与i进行&操作即可。

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    
    #define N 1100
    #define M 15
    #define ll long long
    
    using namespace std;
    
    int n,k,num[N];
    ll f[M][N][N],ans;
    bool flag[N];
    
    int main() {
    	scanf("%d%d",&n,&k);
    	for(int i = 0 ; i < (1<<n) ; i++) {
    		if(!(i & (i<<1))) {
    			flag[i] = 1;
    			int t = i;
    			while(t) {
    				num[i] += (t & 1);
    				t >>= 1;
    			}
    			f[1][num[i]][i] = 1;
    		}
    	}
    	for(int i = 2 ; i <= n ; i++)
    		for(int j = 0 ; j <= k ; j++)
    			for(int l = 0 ; l < (1<<n) ; l++) {
    				if(!flag[l]) continue;
    				if(num[l] > j) continue;
    				for(int last = 0 ; last < (1<<n) ; last++) {
    					if(!flag[last]) continue;
    					if((last & l) || (l<<1)&last || (l>>1)&last) continue;
    					f[i][j][l] += f[i - 1][j - num[l]][last];
    				}
    			}
    	for(int i = 0 ; i < (1<<n) ; i++)
    		ans += f[n][k][i];
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    KVM/QEMU/qemu-kvm/libvirt 概念全解
    OpenStack 实现技术分解 (7) 通用库 — oslo_config
    OpenStack 实现技术分解 (7) 通用库 — oslo_config
    OpenStack 实现技术分解 (6) 通用库 — oslo_log
    OpenStack 实现技术分解 (6) 通用库 — oslo_log
    模拟用户注册功能
    007-解决下载文件【中文文件名】乱码
    006-动态生成验证码Servlet代码模板
    CodingLife的CSS样式整理
    Servlet用户登录功能实现
  • 原文地址:https://www.cnblogs.com/Repulser/p/9609402.html
Copyright © 2011-2022 走看看