• 刷题向》关于第一篇状压DP BZOJ1087 (EASY+)


      这是本蒟蒻做的第一篇状压DP,有纪念意义。

      这道题题目对状压DP十分友善,算是一道模板题。

      分析题目,我们发现可以用0和1代表每一个格子的国王情况,

      题目所说国王不能相邻放置,那么首先对于每一行是否合法的判断条件就出来了:就是对于情况X,如果X&(x<<1)==0,即为合法情况。

      同理这样我们就可以得出每一行对于上一行是否合法的条件:(x&y)==0&&(x&(y<<1))==0&&(x&(y>>1))==0

      得出这个结论之后就比较好处理了,枚举行数,当前行情况,上一行情况,以及国王个数情况。

      在对于国王的个数的处理时,不能只考虑上一行自己的国王情况,还要考虑在上一行的情况下,还能有多少国王,这点在对于国王个数的处理时解决。

      然后给出题目

    escription

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

    Input

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

    Output

      方案数。

    Sample Input

    3 2

    Sample Output

    16
    思路已经给出,
    于是愉快的贴出代码
     1 /**************************************************************
     2     Problem: 1087
     3     User: PencilWang
     4     Language: C++
     5     Result: Accepted
     6     Time:28 ms
     7     Memory:8828 kb
     8 ****************************************************************/
     9  
    10 #include<stdio.h>
    11 int n,k,num[1025];
    12 long long ans,f[10][100][1024];
    13 bool s[1025];
    14 int main()
    15 {
    16     scanf("%d%d",&n,&k);
    17     int ass=1<<n;
    18     for(int i=0;i<ass;i++)
    19     {
    20         if((i&(i<<1))==0)
    21         {
    22         int x=i,sb=0;
    23         while(x){sb+=(x&1);x>>=1;}
    24         num[i]=sb;s[i]=true;
    25         f[1][num[i]][i]=1;
    26         }
    27     }
    28     for(int i=1;i<n;i++)
    29         {
    30         for(int x=0;x<ass;x++)
    31             {
    32             if(s[x])
    33             for(int y=0;y<ass;y++)
    34                 {
    35                 if(s[y])
    36                     {
    37                     if((x&y)==0&&((x>>1)&y)==0&&((x<<1)&y)==0)
    38                         for(int z=num[x];z+num[y]<=k;z++)
    39                             f[i+1][z+num[y]][y]+=f[i][z][x];
    40                     }
    41                 }
    42             }
    43         }
    44     for(int i=0;i<ass;i++)
    45     {
    46     ans+=f[n][k][i];
    47     }
    48     printf("%lld",ans);
    49     return 0;
    50 }
    51 
    1087
  • 相关阅读:
    约瑟夫环-我的解答与迷宫
    数据结构实验一
    typedef struct 是什么意思
    编程名言名句
    创建单链表
    离散实验一
    Angela Merkel poised for record poll win and historic third term
    我的生活计划-贵在执行,贵在坚持
    考研经验
    2010年河南省普通高校招生本科一批院校 平行投档分数线(理科)
  • 原文地址:https://www.cnblogs.com/PencilWang/p/5953276.html
Copyright © 2020-2023  润新知