zoukankan      html  css  js  c++  java
  • JZOJ 1213. 棋盘上的士兵

    题目

    Description

           话说Jby发明了一个取石子游戏之后,一下就被聪明的你破解了….
           这次他又搞了一个新的游戏来折磨游戏者;
            Jby会给定的一个N*N的棋盘,而且要求你在棋盘中放M个士兵,使得士兵不能互相攻击,你的任务是求出有多少种不同的方案。对于每个士兵,他的攻击范围是他的对角线。如图所示: 
     

    Input

    仅有一行,两个数N和M。分别表示棋盘的大小和要放士兵的个数。

    Output

    仅有一行,表示方案数。
     

    Sample Input

    3 4

    Sample Output

    8
     

    Data Constraint

    对于60%的数据,N<=8,1<=m<=2*N-2
    对于100%的数据,N<=15,1<=m<=2*N-2,且答案在Int64范围以内!!

     

    分析

    • 正解还真的是状压但是我不知道数组怎么开于是只有60?

     

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 using namespace std;
     6 int n,m;
     7 long long map[32][32];
     8 long long f[2][1<<20];
     9 long long a[32]; 
    10 void dfs(int x,int y)
    11 {
    12     if (x>(n+n)/2) return;
    13     map[x][y]=0;
    14     dfs(x+1,y-1),dfs(x+1,y+1);
    15 }
    16 int main ()
    17 {
    18     freopen("chess.in","r",stdin);
    19     freopen("chess.out","w",stdout);
    20     cin>>n>>m;
    21     for (int i=1;i<=n+n-1;i++) for (int j=1;j<=n+n-1;j++) map[i][j]=1;
    22     dfs(1,(n+n)/2);
    23     for (int i=(n+n)/2+1,k=2;i<=n+n-1;i++,k+=2) for (int j=1;j<=n+n-1;j++) map[i][j]=map[i-k][j];
    24     for (int i=1;i<=n+n-1;i++) for (int j=1;j<=n+n-1;j++) a[i]=(a[i]<<1)+map[i][j];
    25     int maxn=(1<<(n+n-1))-1;
    26     f[0][(1<<(n+n)/2-1)]=1;
    27     f[0][0]=1;
    28     int nn=n+n-1,x=0;
    29     for (int i=2;i<=nn;i++)
    30     {
    31         x^=1;
    32         for (int j=0;j<=maxn;j++)
    33         {
    34                 f[x][j]+=f[x^1][j];
    35                 for (int k=1;k<=nn;k++)
    36                 {
    37                     if (!(j&(1<<k-1))&&!(a[i]&(1<<k-1)))
    38                     f[x][j|(1<<k-1)]+=f[x^1][j];
    39                 }
    40         }
    41         memset(f[x^1],0,sizeof(f[x^1]));
    42     }
    43     long long ans=0;
    44         for (int j=0;j<=maxn;j++)
    45             if (__builtin_popcount(j)==m) ans+=f[x][j];
    46     cout<<ans;
    47 }

     

    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    Wildcard Matching
    【Unity3D游戏开发】NGUI之DrawCall数量 (四)
    POJ1328 Radar Installation 【贪心&#183;区间选点】
    [C/C++标准库]_[0基础]_[怎样实现std::string自己的Format(sprintf)函数]
    Android程序崩溃异常收集框架
    括号配对问题
    android dp 和 px 的相互转换
    freemarker写select组件报错总结(四)
    [redis]redis概述
    oracle数据库权限管理
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11187464.html
Copyright © 2011-2022 走看看