zoukankan      html  css  js  c++  java
  • BZOJ 1087 互不侵犯King 状态压缩DP

    题目链接:

    https://www.lydsy.com/JudgeOnline/problem.php?id=1087

    题目大意;

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

    思路:

    状态压缩,预处理出每一行的合法状态,连续的两个1在一起的状态为不合法状态。

    预处理出从上一行到下一行的合法情况,直接每一行推过来即可。

     1 #include<bits/stdc++.h>
     2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
     3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
     4 #define Min(a, b) ((a) < (b) ? (a) : (b))
     5 #define Mem(a) memset(a, 0, sizeof(a))
     6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
     7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
     8 #define lson ((o)<<1)
     9 #define rson ((o)<<1|1)
    10 #define Accepted 0
    11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 typedef long long ll;
    21 const int maxn = 2000000 + 10;
    22 const int MOD = 1000000007;//const引用更快,宏定义也更快
    23 const int INF = 1e9 + 7;
    24 const double eps = 1e-10;
    25 const double pi = acos(-1);
    26 
    27 bool Map[520][520];
    28 bool no[520];//判断状态i是否不合法
    29 ll dp[10][520][100];//dp[i][j][k] 表示第i行状态为j,且当前放置的数目为k
    30 int n, k;
    31 void init()
    32 {
    33     for(int x = 0; x < (1<<n); x++)
    34         for(int i = 0; i < n - 1; i++)
    35             if((x&(1<<i))&&(x&(1<<(i+1)))){no[x] = 1;break;}
    36     for(int x = 0; x < (1<<n); x++)if(!no[x])
    37     {
    38         for(int y = 0; y < (1<<n); y++)if(!no[y])
    39         {
    40             bool flag = 1;
    41             for(int i = 0; i < n; i++)if(x&(1<<i))
    42             {
    43                 if(y&(1<<i)){flag = 0; break;}
    44                 if(i != 0 && (y&(1<<(i-1)))){flag = 0; break;}
    45                 if(i != n && (y&(1<<(i+1)))){flag = 0; break;}
    46             }
    47             Map[x][y] = flag;
    48         }
    49     }
    50 }
    51 inline int f(int x)
    52 {
    53     int ans = 0;
    54     for(int i = 0; i < n; i++)if(x&(1<<i))ans++;
    55     return ans;
    56 }
    57 int main()
    58 {
    59     cin >> n >> k;
    60     init();
    61     for(int i = 0; i < (1<<n); i++)if(!no[i])dp[1][i][f(i)] = 1;
    62     for(int i = 2; i <= n; i++)
    63         for(int x = 0; x < (1<<n); x++)if(!no[x])//该行状态
    64             for(int y = 0; y < (1<<n);y++)if(!no[y] && Map[y][x])//上一行状态
    65             {
    66                 int tmp = f(x);
    67                 for(int num = 0; num + tmp <= k; num++)
    68                     dp[i][x][num + tmp] += dp[i - 1][y][num];
    69             }
    70     ll ans = 0;
    71     for(int i = 0; i < (1<<n); i++)if(!no[i])ans += dp[n][i][k];
    72     cout<<ans<<endl;
    73     return 0;
    74 }
  • 相关阅读:
    原生ajax四部曲
    jquery ajax参数
    java String format占位符
    servlet是什么
    直接插入排序算法
    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的--20135334赵阳林
    信息安全系统设计基础第一周学习总结
    信息安全系统设计基础实验五:通讯协议设计
    信息安全系统设计第二次&第四次实验
    信息安全系统设计基础第一次实验报告
  • 原文地址:https://www.cnblogs.com/fzl194/p/9737400.html
Copyright © 2011-2022 走看看