BZOJ

洛谷

\(Description\)

给定\(n,m,c\)。\(Q\)次询问,每次询问给定\(2*c\)的模板串,求它在多少个\(n*m\)的棋盘中出现过。棋盘的每个格子有三种状态。

\(n\leq 100,m\leq 12,c\leq 6,Q\leq 5\)。

\(Solution\)

模板串只有\(2\)行,把它拆成两个串,考虑轮廓线DP。

对于\((i,j)\)这个格子,只需要考虑\((i-1,j)\)是否匹配了模式串的第一行,\((i,j)\)匹配到模式串第二行的哪。

所以令\(f[i][j][S][x][y]\)表示,当前为\((i,j)\),\(i-1\)行匹配了模式串第一行的位置状态为\(S\)(\(S\)第\(k\)位为\(1\)说明\((i-1,k)\)匹配了第一行),第\(i\)行匹配到模式串第一行的位置\(x\),匹配到第二行\(y\)。

转移时枚举三种字符,用KMP预处理会跳到哪一位。

复杂度\(O(n*m*2^{m-c+1}*c^2)\)(\(S\)只需记\(m-c+1\)位)。

  1. //2392kb 792ms
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define mod 1000000007
  6. #define Mod(x) x>=mod&&(x-=mod)
  7. #define Add(x,v) (x+=v)>=mod&&(x-=mod)
  8. typedef long long LL;
  9. const int N=13;
  10. const LL LIM=(LL)1e18;
  11. int f[2][(1<<12)+1][7][7];
  12. struct KMP
  13. {
  14. int s[N],fail[N],to[N][3];
  15. char tmp[N];
  16. void Build(const int n)
  17. {
  18. scanf("%s",tmp+1);
  19. for(int i=1; i<=n; ++i) s[i]=tmp[i]=='W'?0:(tmp[i]=='B'?1:2);
  20. for(int i=2,j=0; i<=n; ++i)
  21. {
  22. while(j && s[i]!=s[j+1]) j=fail[j];
  23. fail[i]=s[i]==s[j+1]?++j:0;
  24. }
  25. s[n+1]=233;
  26. for(int i=0; i<=n; ++i)
  27. for(int c=0; c<3; ++c)
  28. {
  29. int j=i;
  30. while(j && s[j+1]!=c) j=fail[j];
  31. to[i][c]=s[j+1]==c?j+1:0;
  32. }
  33. }
  34. }s1,s2;
  35. inline void Clear(int (*f)[7][7],const int lim,const int C)
  36. {
  37. for(int s=0; s<=lim; ++s)
  38. for(int a=0; a<=C; ++a)
  39. for(int b=0; b<=C; ++b) f[s][a][b]=0;
  40. }
  41. int main()
  42. {
  43. int n,m,C,Q; scanf("%d%d%d%d",&n,&m,&C,&Q);
  44. int lim=(1<<m-C+1)-1; LL pw3=1;
  45. for(int i=n*m; i; --i) pw3=3ll*pw3, pw3>=LIM&&(pw3%=mod);
  46. pw3%=mod;
  47. while(Q--)
  48. {
  49. s1.Build(C), s2.Build(C);
  50. int p=0; memset(f[p],0,sizeof f[p]);
  51. f[p][0][0][0]=1;
  52. for(int i=1; i<=n; ++i)
  53. {
  54. Clear(f[p^1],lim,C);// memset(f[p^1],0,sizeof f[p^1]);//状态少啊
  55. for(int s=0; s<=lim; ++s)
  56. {
  57. LL tmp=0;
  58. for(int a=0; a<=C; ++a)
  59. for(int b=0; b<=C; ++b)
  60. tmp+=f[p][s][a][b];
  61. f[p^1][s][0][0]=tmp%mod;
  62. }
  63. p^=1;
  64. for(int j=1; j<=m; ++j)
  65. {
  66. p^=1, Clear(f[p],lim,C);// memset(f[p],0,sizeof f[p]);
  67. for(int s=0; s<=lim; ++s)
  68. for(int a=0; a<=C; ++a)
  69. for(int b=0,v; b<=C; ++b)
  70. if((v=f[p^1][s][a][b]))
  71. for(int c=0; c<3; ++c)
  72. {
  73. int ta=s1.to[a][c],tb=s2.to[b][c];
  74. if(j<C) Add(f[p][s][ta][tb],v);
  75. else if(!(s>>j-C&1))
  76. if(ta!=C) Add(f[p][s][ta][tb],v);
  77. else Add(f[p][s|(1<<j-C)][ta][tb],v);
  78. else if(tb!=C)
  79. if(ta!=C) Add(f[p][s^(1<<j-C)][ta][tb],v);
  80. else Add(f[p][s][ta][tb],v);
  81. }
  82. }
  83. }
  84. LL ans=0;
  85. for(int s=0; s<=lim; ++s)
  86. for(int a=0; a<=C; ++a)
  87. for(int b=0; b<=C; ++b) ans+=f[p][s][a][b];
  88. printf("%d\n",(int)((pw3+mod-ans%mod)%mod));
  89. }
  90. return 0;
  91. }

BZOJ.4572.[SCOI2016]围棋(轮廓线DP)的更多相关文章

  1. 4572: [Scoi2016]围棋 轮廓线DP KMP

    国际惯例的题面:这种题目显然DP了,看到M这么小显然要状压.然后就是具体怎么DP的问题.首先我们可以暴力状压上一行状态,然后逐行转移.复杂度n*3^m+3^(m*2),显然过不去. 考虑状态的特殊性, ...

  2. [LOJ#2017][轮廓线DP][KMP]「SCOI2016」围棋

    题目传送门 看到 \(m\le 12\) 和 \(c\le 6\) ,容易想到状压 DP 考虑转化成 \(3^{nm}\) 减去不合法的方案数,轮廓线 DP :\(f[i][j][S][k][h]\) ...

  3. 轮廓线DP POJ3254 && BZOJ 1087

    补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点: 5 6 7 8 9 1 2 3 4 如此设置轮廓线标号,转移的时候直接把当前j位改成0或者1就行了.注意多记录些信息对简化代码是很有帮 ...

  4. 【BZOJ 4572】【SCOI 2016】围棋

    http://www.lydsy.com/JudgeOnline/problem.php?id=4572 轮廓线DP:设\(f(i,j,S,x,y)\). \(S\)表示\((i,1)\)到\((i, ...

  5. BZOJ4572: [Scoi2016]围棋

    Description 近日,谷歌研发的围棋AI—AlphaGo以4:1的比分战胜了曾经的世界冠军李世石,这是人工智能领域的又一里程碑. 与传统的搜索式AI不同,AlphaGo使用了最近十分流行的卷积 ...

  6. [SCOI2016]围棋

    Description 近日,谷歌研发的围棋AI-AlphaGo以4:1的比分战胜了曾经的世界冠军李世石,这是人工智能领域的又一里程碑.与传统的搜索式AI不同,AlphaGo使用了最近十分流行的卷积神 ...

  7. HDU4804 Campus Design 轮廓线dp

    跟上面那篇轮廓线dp是一样的,但是多了两个条件,一个是在原图上可能有些点是不能放的(即障碍),所以转移的时候要多一个判断color[i][j]是不是等于1什么的,另外一个是我们可以有多的1*1的骨牌, ...

  8. POJ2411 Mondriaan's Dream 轮廓线dp

    第一道轮廓线dp,因为不会轮廓线dp我们在南京区域赛的时候没有拿到银,可见知识点的欠缺是我薄弱的环节. 题目就是要你用1*2的多米诺骨排填充一个大小n*m(n,m<=11)的棋盘,问填满它有多少 ...

  9. UVA - 11270 轮廓线DP

    其实这题还能用状压DP解决,可是时间达到2000ms只能过掉POJ2411.状压DP解法详见状压DP解POJ2411 贴上POJ2411AC代码 : 2000ms 时间复杂度h*w*(2^w)*(2^ ...

随机推荐

  1. Metasploit渗透测试模块(一)

    1.Metasploit模块加载 初始化界面,成功要加载数据库 查看 Metasploit中已近存在的漏洞模块使用 show payloads

  2. 使用git克隆项目、从dev分支上更新代码以及将代码提交到Coding(或GitHub)上面

    本教程的目的: 这是个crm项目中,有两个分支一个是master 和 dev ,master主分支,不允许提交代码,我要拉去dev分支上最新的代码,并将修改后的项目,在推送到dev分支上. 一. 1. ...

  3. Java 11 这 8 个逆天新特性教你写出更牛逼的代码!

    美国时间2018年 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本. 为什么说是长期版本,看下面的官方发布的支持路线图表. 可以看出 Jav ...

  4. 论文阅读笔记二十六:Fast R-CNN (ICCV2015)

    论文源址:https://arxiv.org/abs/1504.08083 参考博客:https://blog.csdn.net/shenxiaolu1984/article/details/5103 ...

  5. cnetos 7 mariadb 集群报错分析解答

    1.故障1:通过查看/var/log/message 发现报错 2017-04-14 14:44:10 139845276428544 [ERROR] WSREP: It may not be saf ...

  6. 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)

    一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件. 在Spring Cloud中,有分布式配置中心组件spring cloud confi ...

  7. Update openssh7.9 on centos6

    一.制作RPM安装包1)依赖安装yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel ...

  8. SQL Server Profiler的简单使用

    SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...

  9. WPF 下两种图片合成或加水印的方式(转载)

    来源:http://www.cnblogs.com/lxblog/ 最近项目中应用多次应用了图片合成,为了今后方便特此记下. 在WPF下有两种图片合成的方式,一种还是用原来C#提供的GDI+方式,命名 ...

  10. C#default关键字(泛型代码中的默认关键字)

    在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T:T 是引用类型还是值类型.如果 T 为值类型,则它是数值还是结构.给定参数化类型 T 的一个变量 t,只有 ...