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

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

    所得的方案数

    输入输出样例

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


    用二进制压缩状态,dp
    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<algorithm>
    #include<math.h>
    #include<string.h>
    using namespace std;
    int c[1500],f[50][2000][2000],n,k,all;
    bool f1[2000],f2[2000][2000];
    void first()
    {
      int t,x,i=0;
        for(;i<all;i++)
            if((i&(i>>1))==0)
            {
                for(t=0,x=i;x;x/=2)t+=x&1;
                c[i]=t;
                f1[i]=true;
            }
        for(int i=0;i<all;i++)
          if(f1[i])
            for(int j=0;j<all;j++)
              if(f1[j])
                if((i&j)==0&&(i&(j>>1))==0&&(j&(i>>1))==0)
                    f2[i][j]=true;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        if(k>(n+1)/2*(n+1)/2)
        {
            cout<<0;
            return 0;
        }
        all= 1<<n ;
        first();    
        for(int i=0;i<all;i++)        f[0][c[i]][i]=1;    
         int i,j,k1,p;
        for(i=1;i<n;i++)
            for(j=0;j<all;j++)if(f1[j])          
                for(k1=0;k1<all;k1++)if(f2[j][k1])                
                     for(p=c[j];p+c[k1]<=k;p++)
                        f[i][p+c[k1]][k1]+=f[i-1][p][j];
        int ans=0;
        for(i=0,n--;i<all;i++) ans+=f[n][k][i];
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    PHP 学习轨迹
    beego 遇到的一些问题
    Fiddler 502问题
    SourceTree
    Trait
    PHP PSR 标准
    解决MySQL联表时出现字符集不一样
    Git 代码管理命令
    PHP 运行相关概念
    CentOS 7
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7305990.html
Copyright © 2011-2022 走看看