• 状压dp--P1896互不侵犯


    直接从复习笔记里扒下来了

    有学长跟我说状压dp是oier的本能,惊,是我太菜了,不想写了,溜达溜达吃完饭再写吧。

    滚回来写博客了,就题讲dp,P1896互不侵犯

    状态定义:dp[i][j][k]表示第i行的状态为s[j],一共放了k个国王的方案数

    状态转移:如果合法,方案数就相加

    如果不考虑每行间的相对影响,每一行只需要考虑是否有左右相邻的情况,所以我们可以预处理出每一行的可能情况,再判断行和行之间的合法性。

    如何判断合法:

    1、判断左右是否合法 i&i<<1

    2、判断左上是否合法 i&j<<1

    3、判断右上是否合法 i&j>>1

    4、判断上下是否合法 i&j

    预处理每一行的可能情况:

    代码:

     1 inline void init(){
     2   cnt=0;
     3   for (int i = 0;i < (1<<n);i++){
     4     if (i&(i<<1)) continue;
     5     int sum=0;
     6     for (int j = 0;j < n;j++) if(i&(1<<j)) ++sum;
     7     s[++cnt]=i;
     8     num[cnt]=sum;
     9   }
    10   return;
    11 }

    完整代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 using namespace std;
     5 #define ll long long
     6 long long dp[15][200][200],ans;
     7 int num[200],s[200];
     8 int n,k,cnt;
     9 inline void init(){
    10   cnt=0;
    11   for (int i = 0;i < (1<<n);i++){
    12     if (i&(i<<1)) continue;
    13     int sum=0;
    14     for (int j = 0;j < n;j++) if(i&(1<<j)) ++sum;
    15     s[++cnt]=i;
    16     num[cnt]=sum;
    17   }
    18   return;
    19 }
    20 int main(){
    21   scanf ("%d%d",&n,&k);
    22   init();
    23   dp[0][1][0]=1;
    24   for (int i = 1;i <= n;i++){
    25     for (int j = 1;j <= cnt;j++){
    26       for (int l = 0;l <= k;l++){
    27     if (l>=num[j]){
    28       for (int t = 1;t <= cnt;t++){
    29         if (!(s[t]&s[j])&&!(s[t]&(s[j]<<1))&&!(s[t]&(s[j]>>1))) dp[i][j][l]+=dp[i-1][t][l-num[j]];                                     }
    30     }
    31       }
    32     }
    33   }
    34   for (int i = 1;i <= cnt;i++) ans+=dp[n][i][k];
    35   cout<<ans<<endl;
    36   return 0;
    37 }
  • 相关阅读:
    算法学习:二分法从入门到精通
    TypeScript筑基笔记一:Visual Studio Code 创建Typescript文件和实时监控
    LeetCode 92. 反转链表 II
    LeetCode 1525. 字符串的好分割数目
    字节跳动-people后台一面面经
    LeetCode 117. 填充每个节点的下一个右侧节点指针 II
    LeetCode 1529. 灯泡开关 IV
    LeetCode 165. 比较版本号
    LeetCode 312. 戳气球
    LeetCode 605. 种花问题
  • 原文地址:https://www.cnblogs.com/very-beginning/p/13691927.html
Copyright © 2020-2023  润新知