zoukankan      html  css  js  c++  java
  • 【BZOJ 1087】[SCOI2005]互不侵犯King

    Description

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

    Input

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

    Output

    方案数。

    Sample Input

    3 2

    Sample Output

    16
    同学很早之前打表过了,orz
    这题正解状压DP,f[i][s][k]表示第i行上一行的状态为S,选了k个
    预处理出所有可行状态DP就好了
     1 #include<cstdio>
     2 #include<cstring>
     3 #define ll long long 
     4 using namespace std;
     5 int gs[520],a[520][11];
     6 bool pd[520];
     7 int n,K;
     8 ll ans,f[11][520][90];
     9 bool ok(int x,int y){
    10     for(int i=1;i<=9;i++) if(a[x][i]&&(a[y][i]||a[y][i-1]||a[y][i+1])) return 0;
    11     return 1;
    12 }
    13  
    14 int main(){
    15     scanf("%d%d",&n,&K);
    16     memset(pd,1,sizeof(pd));
    17     for(int i=1;i<=(1<<n)-1;i++){
    18         int tmp=i,cnt=0;
    19         while(tmp){
    20             a[i][++cnt]=tmp&1;gs[i]+=1&tmp;
    21             tmp>>=1;
    22         }
    23         for(int j=1;j<=n;j++) if(a[i][j]==1&&a[i][j+1]==1){
    24             pd[i]=0;break;
    25         }
    26         if(pd[i]) f[1][i][gs[i]]+=1;
    27     }
    28     f[1][0][0]=1;
    29     for(int i=2;i<=n;i++)
    30         for(int j=0;j<=(1<<n)-1;j++){
    31             if(!pd[j]) continue;
    32             for(int k=0;k<=(1<<n)-1;k++){
    33                 if(ok(j,k)){
    34                     for(int l=gs[k];l<=K;l++)
    35                     f[i][k][l]+=f[i-1][j][l-gs[k]];
    36                 }
    37             }
    38         }
    39     for(int i=0;i<=(1<<n)-1;i++)if (pd[i]) ans+=f[n][i][K];
    40     printf("%lld",ans);
    41 } 
  • 相关阅读:
    SQL Server需要监控哪些计数器
    将表里的数据批量生成INSERT语句的存储过程 继续增强版
    [Java]
    [Linux] 安装JBoss
    [Spring]
    [Spring]
    [Maven]
    [Maven]
    [Spring MVC]
    [Spring MVC]
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5202604.html
Copyright © 2011-2022 走看看