• Bzoj1087 [SCOI2005]互不侵犯King


    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3558  Solved: 2074
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

      方案数。

    Sample Input

    3 2

    Sample Output

    16

    HINT

     

    Source

    动规 状压DP

    f[行][摆放个数][状态]=方案数

    仿佛状压以后的背包233

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #define LL long long
     8 using namespace std;
     9 const int mxn=100010;
    10 int t[1<<10],cnt=0;
    11 int w[1<<10];
    12 LL f[11][90][1<<10];
    13 int n,k;
    14 inline bool check(int p,int r){
    15     if(p&r)return 0;
    16     if((p<<1)&r)return 0;
    17     if((p>>1)&r)return 0;
    18     return 1;
    19 }
    20 void init(){
    21     int ed=(1<<n)-1;bool flag=0;
    22     for(int i=0;i<=ed;i++){
    23         flag=0;
    24         for(int j=1;j<n;j++){if(((1<<j)&i) && ((1<<(j-1))&i) ){flag=1;break;}};
    25         if(flag)continue;
    26         t[++cnt]=i;
    27         for(int j=0;j<n;j++)if(i&(1<<j))w[cnt]++;
    28     }
    29     return;
    30 }
    31 int main(){
    32     int i,j,c;
    33     scanf("%d%d",&n,&k);
    34     init();
    35     f[0][0][0]=1;
    36 //  int ed=(1<<n)-1;
    37 //  for(i=1;i<=cnt;i++)printf("%d %d
     ",t[i],w[i]);
    38     for(i=1;i<=cnt;i++)f[1][w[i]][i]=1;
    39     for(j=2;j<=n;j++){//40 //                  printf("ck:%d %d :%d %d
    ",k1,k2,t[k1],t[k2]);
    41                     for(c=0;c<=k;c++){//摆放个数 
    42                          
    43                         for(int k1=1;k1<=cnt;k1++){
    44                             for(int k2=1;k2<=cnt;k2++){
    45                                 if(w[k2]<=c && check(t[k1],t[k2]))
    46         //                      printf("j:%d  c:%d
    ",j,c);
    47         //                      printf("%lld
    ",f[j-1][c-w[k2]][k1]);
    48                                 f[j][c][k2]+=f[j-1][c-w[k2]][k1];
    49         //                      printf("%lld
    ",f[j][c][k2]);
    50                             }
    51                         }
    52                     }
    53     }
    54     LL ans=0;
    55     for(i=1;i<=cnt;i++)ans+=f[n][k][i];
    56     printf("%lld
    ",ans);
    57     return 0;
    58 }
  • 相关阅读:
    学习笔记TF034:实现Word2Vec
    学习笔记TF033:实现ResNet
    学习笔记TF032:实现Google Inception Net
    学习笔记TF031:实现VGGNet
    学习笔记TF030:实现AlexNet
    学习笔记TF029:实现进阶卷积网络
    学习笔记TF028:实现简单卷积网络
    学习笔记TF027:卷积神经网络
    学习笔记TF026:多层感知机
    学习笔记TF025:自编码器
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6437971.html
Copyright © 2020-2023  润新知