【BZOJ】1087: [SCOI2005]互不侵犯King

【算法】状态压缩型DP

【题解】http://www.cnblogs.com/xtx1999/p/4620227.html (orz)

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10,e2=530;
long long f[maxn][e2][maxn*maxn];
int n,mk,num[e2],king[e2],ok[e2][e2];
bool selfcheck(int a)
{
    return !(a&(a>>1));
}
int calc(int a)
{
    int cyc=0;
    while(a)
     {
         if(a&1)cyc++;
         a=a>>1;
     }
    return cyc;
}
bool check(int a,int b)
{
    if((a&b)||(a&(b<<1))||(a&(b>>1)))return 0;
    return 1;

}
int main()
{
    scanf("%d%d",&n,&mk);
    int all=(1<<n)-1,tot=0;
    for(int i=0;i<=all;i++)
     {
         if(selfcheck(i))
         {
             num[++tot]=i;
             king[tot]=calc(i);
             //printf("%d\n",i);
         }
     }
    for(int i=1;i<=tot;i++)
     for(int j=1;j<=tot;j++)
      if(!ok[i][j])if(check(num[i],num[j]))
       ok[i][j]=ok[j][i]=1;//,printf("%d %d\n",i,j);
    f[0][1][0]=1;
    for(int i=0;i<=n-1;i++)
     for(int j=1;j<=tot;j++)
      for(int k=0;k<=mk;k++)
       if(f[i][j][k])
        for(int p=1;p<=tot;p++)
         if(ok[j][p]&&k+king[p]<=mk)
          f[i+1][p][k+king[p]]+=f[i][j][k];
    long long ans=0;
    for(int i=1;i<=tot;i++)
     ans+=f[n][i][mk];
    printf("%lld",ans);
    return 0;
}

时间: 2024-12-30 01:32:14

【BZOJ】1087: [SCOI2005]互不侵犯King的相关文章

BZOJ 1087: [SCOI2005]互不侵犯King( 状压dp )

简单的状压dp... dp( x , h , s ) 表示当前第 x 行 , 用了 h 个 king , 当前行的状态为 s . 考虑转移 : dp( x , h , s ) = ∑ dp( x - 1 , h - cnt_1( s ) , s' ) ( s and s' 两行不冲突 , cnt_1( s ) 表示 s 状态用了多少个 king ) 我有各种预处理所以 code 的方程和这有点不一样 ------------------------------------------------

BZOJ 1087 [SCOI2005]互不侵犯King

水状压 预处理可以用的每行的状态,转移的时候判断上下行是否冲突.记得当时刚学的时候听学长讲感觉这题好难呀. 然后智障的第一次空间开小了第二次忘了开LL,RE了一发又WA了一发... #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector>

[SCOI2005]互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4255  Solved: 2458 [Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <=

SCOI2005互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1499  Solved: 872[Submit][Status] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N

[Bzoj1083][SCOI2005]互不侵犯king(状压dp)

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4595  Solved: 2664[Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K &

BZOJ1087:[SCOI2005]互不侵犯King(状压DP)

[SCOI2005]互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 分析: 经典的状压DP题目,可我竟然调了很长时间都没对,后来发现是DP枚举范围错

【BZOJ 1087】[SCOI2005]互不侵犯King

Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 同学很早之前打表过了,orz 这题正解状压DP,f[i][s][k]表示第i行上一行的状态为S,选了k个 预处理出所有

[bzoj1087] [SCOI2005]互不侵犯King

http://www.lydsy.com/JudgeOnline/problem.php?id=1087 一个n*n的棋盘,要在上面放国王,每个国王占领周围3*3的土地,求放置K个国王的方案数量. 一开始感觉结论题就打了个表,打一个8的表只要一两分钟??,虽然说n<=9,但是9的估计要很久...说不定考试那几个小时都打不完. 说说正解吧. 考虑壮压dp,如果按照一个个位置dp需要记录轮廓线以及左上角那个位置的情况,但是显然我们不需要那么复杂. 情况数2^9=512   预先处理好  每种情况是否

_bzoj1087 [SCOI2005]互不侵犯King【dp】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 令f(i, j, k)表示前i列,二进制状态为j,已经用了k个国王的方案数,则 f(i, j, k) = sigma(i - 1, p, k - num[j]),其中可以从p状态转化到j状态,num[j]表示j状态下的国王数. 乍一看可能会超时,因为共有n * 2^n * n^2个状态,即状态数为O(n^3 * 2^n),转移的复杂度为O(2^n),因此总时间复杂度为O(n^3 *