码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P1896 [SCOI2005]互不侵犯King

时间:2017-10-18 00:24:48      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:name   time   一个   names   pac   show   格式   进入   枚举   

题目描述

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

输入输出格式

输入格式:

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

输出格式:

所得的方案数

输入输出样例

输入样例#1:
3 2
输出样例#1:
16

题目链接:https://daniu.luogu.org/problem/show?pid=1896.
解题报告
状压DP经典好题
将放不放king的0/1状态压成一个数.
首先我们要学会一些高端操作:
(1)i&(i>>1)可以判断当前状态i是否合法,
若i&(i>>1)==0表示状态i中没有相邻的king,为合法方案.
若i&(i>>1)!=0表示状态i中有相邻的king,为非法方案.
For example:
[1].i=(1010101)2,i>>1=(101010)2,i&(i>>1)=(0)2.
  为合法方案.
[2].i=(1000111)2,i>>1=(100011)2,i&(i>>1)=(11)2.
  为非法方案.
(2)若有相邻两行状态i和j,
那么满足i&j==0&&(i<<1)&j==0&&(i>>1)&l==0,则相邻两行状态合法,
否则为非法方案.
For example:
[1].i=(100010001)2,
j=(001000100)2,
    i&j=(0)2,(i<<1)&j=(0)2,(i>>1)&j=(0)2.
  为合法方案.
[2].i=(101010101)2,
   j=(010101010)2,
  i&j=(0)2,(i<<1)&j=(10101010)2,(i>>1)&j=(10101010)2.
  为非法方案.
以上均为O(1)复杂度的判断.
进入正题:
先枚举合法状态i中king的个数,
记录到num[i]中.
再定义状态转移方程f[i][j][k],
表示1~i行用了j个数且第i的状态为k的方案数.
初始化f[0][0][0]=1.
先枚举行数i,复杂度
O(n).
再枚举king的个数,复杂度O(m).
接着第i行的状态k,复杂度O(2n).
最后枚举i-1行的状态k,复杂度为O(2n).
判断是否满足条件,进行转移:
 f[i][j][k]=(ll)(f[i][j][k]+f[i-1][j-num[k]][l]).
总复杂度为O(n*m*22n).
最后,ans=∑(i=0,2n-1)f[n][m][i].
AC代码:
#include<cstdio>
#include<iostream>
#define ll long long
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using namespace std;
int num[1025],T;
ll f[10][121][1025];
int n,m;
ll ans;
int main(){
    scanf("%d%d",&n,&m);
    T=(1<<n)-1;
    FOR(i,0,T)
        for(register int k=i;k;k>>=1)
            if(k&1)
                ++num[i];
    f[0][0][0]=1ll;
    FOR(i,1,n)
        FOR(j,0,m)
            FOR(k,0,T)
                if(!((k<<1)&k)&&!((k>>1)&k)&&j>=num[k])
                    FOR(l,0,T)
                        if(!((l<<1)&l)&&!((l>>1)&l)&&!(l&k)&&!((k<<1)&l)&&!((k>>1)&l))
                            f[i][j][k]=(ll)(f[i][j][k]+f[i-1][j-num[k]][l]);
    FOR(k,0,T)
        ans=(ll)(ans+f[n][m][k]);
    cout<<ans<<endl;
    return 0;
}

 


luogu P1896 [SCOI2005]互不侵犯King

标签:name   time   一个   names   pac   show   格式   进入   枚举   

原文地址:http://www.cnblogs.com/Stump/p/7684397.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!