zoukankan      html  css  js  c++  java
  • Luogu P1896 [SCOI2005]互不侵犯

    gate

    第二道状压dp...

    预处理每种状态j所含1的个数为sum[j]

    f[i][j][l]代表第i行,状态为j,当前共有l个国王

    枚举本层状态j,上一层状态k,判断八方向是否有相邻:k&j||(k<<1)&j||(k>>1)&j

    枚举国王数l,则有f[i][j][l] += f[i-1][k][l-sum[j]]

    最后统计f[n][ ][m]即为答案

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    using namespace std;
    
    const int mod = 1e9;
    
    int n,m;
    long long ans;
    int a[10],sum[1<<9+5],g[1<<9+5];
    long long f[10][1<<9+5][100];
    
    int main() {
        scanf("%d%d",&n,&m);
        
        for(int i = 0; i < (1<<n); i++) {
            g[i] = (!((i<<1)&i) && !((i>>1)&i));
            for(int j = 0; (1<<j) <= i; j++)
                if((1<<j)&i) sum[i]++;
            if(g[i]) f[1][i][sum[i]] = 1;
        }
        for(int i = 2; i <= n; i++)
            for(int j = 0; j < (1<<n); j++) {
                if(!g[j]) continue;
                for(int k = 0; k < (1<<n); k++) {
                    if(k&j||(k<<1)&j||(k>>1)&j) continue;
                    for(int l = 0; l <= m; l++)
                        f[i][j][l] += f[i-1][k][l-sum[j]];
                }
            }
    
        for(int i = 0; i < (1<<n); i++)
            ans += f[n][i][m];
        printf("%lld
    ",ans);
        return 0;
    }
    View Code

    题外话:

    以前总觉得状压dp很难,一直不想写这个东西。写了才发现其实没什么...

    只要努力就能克服困难!

  • 相关阅读:
    C语言第三次博客作业---单层循环结构
    C语言第二次博客作业---分支结构
    C语言第一次博客作业
    第0次作业
    第09组 Beta冲刺(1/5)
    第09组 Alpha事后诸葛亮
    第09组 Alpha冲刺(6/6)
    第09组 Alpha冲刺(5/6)
    第09组 Alpha冲刺(4/6)
    第09组 Alpha冲刺(3/6)
  • 原文地址:https://www.cnblogs.com/mogeko/p/11625775.html
Copyright © 2011-2022 走看看