zoukankan      html  css  js  c++  java
  • BZOJ4572: [Scoi2016]围棋

    Description

    近日,谷歌研发的围棋AI—AlphaGo以4:1的比分战胜了曾经的世界冠军李世石,这是人工智能领域的又一里程碑。
    与传统的搜索式AI不同,AlphaGo使用了最近十分流行的卷积神经网络模型。在卷积神经网络模型中,棋盘上每一
    块特定大小的区域都被当做一个窗口。例如棋盘的大小为5×6,窗口大小为2×4,那么棋盘中共有12个窗口。此外
    ,模型中预先设定了一些模板,模板的大小与窗口的大小是一样的。下图展现了一个5×6的棋盘和两个2×4的模板
    。对于一个模板,只要棋盘中有某个窗口与其完全匹配,我们称这个模板是被激活的,否则称这个模板没有被激活
    。例如图中第一个模板就是被激活的,而第二个模板就是没有被激活的。我们要研究的问题是:对于给定的模板,
    有多少个棋盘可以激活它。为了简化问题,我们抛开所有围棋的基本规则,只考虑一个n×m的棋盘,每个位置只能
    是黑子、白子或无子三种情况,换句话说,这样的棋盘共有3n×m种。此外,我们会给出q个2×c的模板。我们希望
    知道,对于每个模板,有多少种棋盘可以激活它。强调:模板一定是两行的。
     

    Input

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

    Output

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

    Sample Input

    3 1 1 2
    B
    W
    B
    B

    Sample Output

    6
    5
     
    考虑补集转换,计算不合法的情况,然后轮廓线DP一下,状态记录为轮廓线上与第一行串是否完全匹配,当前位置与第一行串及第二行串的kmp匹配位置。
    时间复杂度为O(T*N*M*2^M*C^2)
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    typedef long long ll;
    const int mod=1000000007;
    char id[2333];
    void Add(int& x,int y) {x+=y;if(x>=mod) x-=mod;}
    int to1[8][3],to2[8][3];
    void init(char* A,int* f,int c,int tp) {
    	id['W']='0';id['B']='1';id['X']='2';
    	rep(i,0,c-1) A[i]=id[A[i]];
    	rep(i,1,c-1) {
    		int j=f[i];
    		while(j&&A[i]!=A[j]) j=f[j];
    		f[i+1]=A[i]==A[j]?j+1:0;
    	}
    	rep(i,0,c) rep(k,0,2) {
    		int j=i;
    		while(j&&A[j]!=k+'0') j=f[j];
    		if(A[j]==k+'0') j++;
    		if(tp) to2[i][k]=j;
    		else to1[i][k]=j;
    	}
    }
    int n,m,c,f[2][1<<12][8][8],tmp[8];
    char A[8],B[8];
    void solve() {
    	int cur=0;scanf("%s%s",A,B);
    	init(A,tmp,c,0);init(B,tmp,c,1);
    	memset(f,0,sizeof(f));f[0][0][0][0]=1;
    	rep(x,1,n) rep(y,1,m) {
    		cur^=1;memset(f[cur],0,sizeof(f[cur]));
    		rep(S,0,(1<<m)-1) rep(i,0,c) rep(j,0,c) {
    			int& res=f[cur^1][S][i][j];if(!res) continue;
    			rep(k,0,2) {
    				int nx=to1[i][k],ny=to2[j][k],nS=S<<1;
    				if(nS>>m&1) nS^=(1<<m);if(nx==c) nS^=1;
    				if(y>=c&&ny==c&&(S>>(m-1)&1)) continue;
    				Add(f[cur][nS][nx][ny],res);
    			}
    		}
    	}
    	int ans=1;rep(i,1,n*m) ans=(ll)ans*3%mod;
    	rep(S,0,(1<<m)-1) rep(i,0,c) rep(j,0,c) Add(ans,mod-f[cur][S][i][j]);
    	printf("%d
    ",ans);
    }
    int main() {
    	n=read();m=read();c=read();
    	dwn(T,read(),1) solve();
    	return 0;
    }
    

      

  • 相关阅读:
    #一周五# (视频) 手掌四轴Estes 4606,树莓派2和WRTNode,WinHEC 2015深圳
    Android 自定义标题栏
    (视频)《快速创建网站》 4.1 为啥造软件不同于造汽车,为啥是软件就一定会有Bug - 构建开发运维一体化(DevOps)
    (视频) 《快速创建网站》3.4 网站改版3分钟搞定 - WordPress主题安装和备份
    OpenCV由汉字生成图片(透明)----可以对抗论文查重!!!
    Codeforces Round #295 (Div. 2)
    Codeforces Round #294 (Div. 2)
    Codeforces Round #293 (Div. 2)
    Codeforces Round #292 (Div. 2)
    暴力/set Codeforces Round #291 (Div. 2) C. Watto and Mechanism
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5575604.html
Copyright © 2011-2022 走看看