zoukankan      html  css  js  c++  java
  • 状压DP SCOI2005 互不侵犯King

    P1896 [SCOI2005]互不侵犯King

    题目描述

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

    输入输出格式

    输入格式:

    只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

    输出格式:

    所得的方案数

    输入输出样例

    输入样例#1:
    3 2
    
    输出样例#1:
    16


    这是一个显然的问题
    然而我并看不懂wxl和hzwer等神犇的高大上代码


    贴代码
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int s[520];
     7 int num[520];
     8 int states;
     9 long long f[15][110][520];
    10 int n,k;
    11 long long ans;
    12 
    13 int main(){
    14     scanf("%d%d",&n,&k);
    15     for(int i=0;i<(1<<n);i++){
    16         if(i&(i<<1)) continue;
    17         int temp=i;
    18         while(temp){
    19             num[states]+=(temp&1);
    20             temp=temp>>1;
    21         }
    22         s[states++]=i;
    23     }
    24     for(int i=0;i<states;i++)//第一行特处理 
    25         if(num[i]<=k) f[1][num[i]][i]++;
    26     for(int i=2;i<=n;i++)
    27         for(int j=0;j<=k;j++)
    28             for(int t=0;t<states;t++){
    29                 if(num[t]>j) continue;
    30                 for(int q=0;q<states;q++){
    31                     if(num[q]>j-num[t]) continue;
    32                     if(s[t]&s[q]) continue;
    33                     if((s[t]<<1)&s[q]) continue;
    34                     if(s[t]&(s[q]<<1)) continue;
    35                     f[i][j][t]+=f[i-1][j-num[t]][q];
    36                 }
    37             }
    38     for(int i=0;i<states;i++) ans+=f[n][k][i];
    39     printf("%lld",ans);
    40     return 0; 
    41 }
  • 相关阅读:
    C语言数组和字符串函数
    C语言控制语句
    C语言输入输出函数
    C语言运算符
    C语言数据类型
    嵌入式开发基础知识
    VI编辑器的使用
    Linux文件系统和目录相关命令
    前段之必学(转载)
    26个高效工作的小技巧(转载)
  • 原文地址:https://www.cnblogs.com/zwube/p/6808534.html
Copyright © 2011-2022 走看看