zoukankan      html  css  js  c++  java
  • 【bzoj4572 scoi2016】围棋

    题目描述

    近日,谷歌研发的围棋AI—AlphaGo以4:1的比分战胜了曾经的世界冠军李世石,这是人工智能领域的又一里程碑。

    与传统的搜索式AI不同,AlphaGo使用了最近十分流行的卷积神经网络模型。在卷积神经网络模型中,棋盘上每一块特定大小的区域都被当做一个窗口。例如棋盘的大小为5*6,窗口大小为2*4,那么棋盘中共有12个窗口。此外,模型中预先设定了一些模板,模板的大小与窗口的大小是一样的。

    下图展现了一个5*6的棋盘和两个2*4的模板。

    对于一个模板,只要棋盘中有某个窗口与其完全匹配,我们称这个模板是被激活的,否则称这个模板没有被激活。

    例如图中第一个模板就是被激活的,而第二个模板就是没有被激活的。我们要研究的问题是:对于给定的模板,有多少个棋盘可以激活它。为

    了简化问题,我们抛开所有围棋的基本规则,只考虑一个n*m的棋盘,每个位置只能是黑子、白子或无子三种情况,换句话说,这样的棋盘共有3n*m种。此外,我们会给出q个2*c的模板。

    我们希望知道,对于每个模板,有多少种棋盘可以激活它。强调:模板一定是两行的。

    输入输出格式

    输入格式:

    输入数据的第一行包含四个正整数n,m,c和q,分别表示棋盘的行数、列数、模板的列数和模板的数量。随后2×q行,每连续两行描述一个模板。其中,每行包含c个字符,字符一定是'W','B'或'X'中的一个,表示白子、黑子或无子三种情况的一种。N<=100,M<=12,C<=6,Q<=5

    输出格式:

    输出应包含q行,每行一个整数,表示符合要求的棋盘数量。由于答案可能很大,你只需要输出答案对1,000,000,007取模后的结果即可。

    题意:

    nm的棋盘,有一个2*c的模板,nmc都比较小,求一共有多少种nm可以包含模板;

    题解:

    ①反过来求不包含的方案数;

    轮廓线dp。。。。把模板串分成两份,用f[i][j][S][x][y]表示在ij位置,i行的ij和第一个模板匹配到了x,和第二个模板匹配到了y,S记录红色区域(只需记录m-c+1个)和第一个模板串匹配的情况。只有在S&(1<<m-c)&&y==c时不转移;

    ③ij可以不用存,滚动一下方便点,注意行更新时所有f[S][x][y]都要转移到f[S][0][0],初始状态为f[0][0][0] = 1,还有当x,y到了c时最后应该变成nxt[c];

    ③用kmp预处理nxt,再预处理出在i位置上加上j后的失配指针ta[i][j],tb[i][j];

     

     1 #include<cstdio>
     2 #include<iostream>
     3 const int mod = 1e9+7,N = 20;
     4 using namespace std;
     5 int n,m,c,q,a[N],b[N],nxt[N],na,nb,f[(1<<12)][N][N],g[(1<<12)][N][N],ta[N][3],tb[N][3],U;
     6 char gc(){
     7     static char *p1,*p2,s[1000000];
     8     if(p1==p2) p2=(p1=s)+fread(s,1,1000000,stdin);
     9     return (p1==p2)?EOF:*p1++;
    10 }
    11 int rd(){
    12     int x=0; char c = gc();
    13     while(c<'0'||c>'9') c = gc();
    14     while(c>='0'&&c<='9') x=x*10+c-'0',c=gc();
    15     return x;
    16 }
    17 char gt(){
    18     char c; do c=gc(); while(!isalpha(c));
    19     return (c=='W')?0:(c=='B')?1:2;
    20 }
    21 void clear(){for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++)g[S][x][y]=0;}
    22 void copy(){for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++)f[S][x][y]=g[S][x][y];}
    23 void up(int &x,int y){x+=y;if(x>=mod)x-=mod;}
    24 int main()
    25 {    freopen("bzoj4572.in","r",stdin);
    26     freopen("bzoj4573.out","w",stdout);
    27     n=rd();m=rd();c=rd();q=rd();
    28     while(q--){
    29     for(int i=1;i<=c;i++) a[i] = gt();
    30     for(int i=1;i<=c;i++) b[i] = gt();
    31     nxt[1]=0;
    32     for(int i = 2,j=0;i <= c;nxt[i++]=j){
    33         while(j&&a[j+1]!=a[i]) j=nxt[j];
    34         if(a[j+1]==a[i]) j++;
    35     }
    36     na=nxt[c];
    37     for(int i = 0;i < c;i++) for(int j = 0,k;j < 3;j++){
    38         for(k=i;k&&a[k+1]!=j;k=nxt[k]);
    39         if(a[k+1]==j) k++; ta[i][j] = k;
    40     }
    41     nxt[1]=0;
    42     for(int i = 2,j=0;i <= c;nxt[i++]=j){
    43         while(j&&b[j+1]!=b[i]) j=nxt[j];
    44         if(b[j+1]==b[i]) j++;
    45     }
    46     nb=nxt[c];
    47     for(int i = 0;i < c;i++) for(int j = 0,k;j < 3;j++){
    48         for(k=i;k&&b[k+1]!=j;k=nxt[k]);
    49         if(b[k+1]==j) k++; tb[i][j] = k;
    50     }
    51     U = (1<<m-c+1);
    52     for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++) f[S][x][y]=0;
    53     f[0][0][0]=1;
    54     for(int i = 1;i <= n;i++){
    55         clear();
    56         for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++)if(f[S][x][y])up(g[S][0][0],f[S][x][y]);
    57         copy();
    58         for(int j=1;j<=m;j++){
    59             clear();
    60             for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++)if(f[S][x][y])for(int k=0;k<3;k++){
    61                 int E = S; 
    62                 if(j>=c&&E&(1<<j-c)) E^=(1<<j-c);
    63                 int A = ta[x][k];
    64                 if(A==c){
    65                     E|=(1<<j-c);
    66                     A=na;
    67                 }
    68                 int B = tb[y][k];
    69                 if(B==c){
    70                     if(S&(1<<j-c)) continue;
    71                     B = nb;
    72                 }
    73                 up(g[E][A][B],f[S][x][y]);
    74             }
    75             copy();
    76         }
    77     }
    78     int ans = 1;
    79     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) ans=1ll*ans*3%mod;
    80     for(int S=0;S<U;S++)for(int x=0;x<c;x++)for(int y=0;y<c;y++) ans=(ans-f[S][x][y]+mod)%mod;
    81     printf("%d
    ",ans);
    82     }
    83     return 0;
    84 }//by tkys_Austin; 

     

     

  • 相关阅读:
    策略模式 Web.Net版 [原理+代码] 鸭子呱呱叫
    关于onMouseOut违背逻辑关系的解决办法!
    js漂浮组件发布 ppFloat.js.1.0
    (转)跟我一起制作数据采集获取淘宝网店宝贝数据信息(二)
    (转)WCF学习笔记(一)——WCF基础
    (转)IIS负载均衡Application Request Route详解第一篇: ARR介绍
    (转)【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
    (转)HTTP与Tcp协议下双工通信的差异
    (转)一个仿新浪微博的网站 mvc ado
    (转)微软开源的项目和架构学习
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/8648468.html
Copyright © 2011-2022 走看看