zoukankan      html  css  js  c++  java
  • SGU 223 国王 状压DP

    在 n×的棋盘上放 kk 个国王,国王可攻击相邻的 88 个格子,求使它们无法互相攻击的方案总数。

    状压DP是一种比较暴力的DP。

    首先dp[i][j][k]表示前i行放置k个国王,且当前行状态是j的方案数。

    转移方程 dp[i][j][k] = dp[i - 1][m][k - sum[k]]

    sum[k]表示第k个合法状态的放置的国王个数。

    什么叫第k个合法状态。由于每行的放置规则是有限的,所以可以预处理出合法状态记录到sum里和一个st数组表示第i个合法状态的国王个数。

    最后只要求 1 <= i <= cnt 下dp[n][i][k] cnt是合法状态数

    ll dp[12][1 << 10 + 5][105];
    int st[1 << 10 + 5];
    int sum[1 << 10 + 5];
    
    bool check(int x, int y) {
        if ((x & y) || (x & (y << 1)) || (x & (y >> 1))) return false;
        return true;
    }
    
    int main() {
        int n = readint();
        int k = readint();
        int cnt = 0;
        for (int i = 0; i < 1 << n; i++) {
            if (!(i & (i << 1))) {
                st[++cnt] = i;
                sum[cnt] = bitcount(i);
            }
        }
        for (int i = 1; i <= cnt; i++) dp[1][i][sum[i]] = 1;
        for (int i = 2; i <= n; i++) 
            for (int j = 1; j <= cnt; j++)
                for (int m = sum[j]; m <= k; m++)
                      for (int jj = 1; jj <= cnt; jj++)
                          if (check(st[j], st[jj])) dp[i][j][m] += dp[i - 1][jj][m - sum[j]];
        ll sum = 0;
        for (int i = 1; i <= cnt; i++) sum += dp[n][i][k];  
        Put(sum);
    }
  • 相关阅读:
    Hadoop技术内幕——Hadoop配置信息处理
    协程,线程池
    线程知识点(锁,信号量,队列,条件)
    进程的概念
    socketserver网络编程简单的小例子
    socket 发送文件
    网络编程
    正则表达式
    面对对象--多态封装
    创建可管理的属性:property
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13479468.html
Copyright © 2011-2022 走看看