「SCOI2016」围棋

打CF后困不拉基的,搞了一上午...

考虑直接状压棋子,然后发现会t

考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串

于是状态可以\(2^m\)压住了,但还是会T

考虑到复杂度瓶颈在于每行的状态都要枚举上一行的状态,是按行转移的。

那么如果做一个轮廓线,就可以按格子转移

考虑有那些状态,当前格子\(i,j\),当前轮廓线是否可以匹配第一行的串的状态\(s\)

然后你试试发现如果想好好转移

得存一个\((i,j)\)匹配到第一行串的位置\(x\),和第二行串的位置\(y\)

这里的思考方向倾向于先想转移,转移不了再加状态

然后发现这个匹配的过程可以使用KMP优化,转移的均摊是\(O(1)\)的

复杂度\(O(nm2^{m-c+1}c^2)\)

这里复杂度写成\(2^m\)可能不太稳...


Code:

#include <cstdio>
#include <cctype>
#include <cstring>
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
const int mod=1e9+7;
void add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
void mul(int &x,int y){x=1ll*x*y%mod;}
int n,m,c,q,dp[2][1<<12][7][7];
int nxt1[12],nxt2[12],d1[12],d2[12];
char s1[12],s2[12];
void init(char *s,int *d,int *nxt)
{
for(int i=1;i<=c;i++) d[i]=(s[i]=='W'?2:(s[i]=='B'));
for(int j=0,i=2;i<=c;i++)
{
while(j&&d[j+1]!=d[i]) j=nxt[j];
if(d[j+1]==d[i]) ++j;
nxt[i]=j;
}
}
int get(int *nxt,int p,int col,int *d)
{
while(p&&d[p+1]!=col) p=nxt[p];
if(d[p+1]==col) ++p;
return p;
}
int main()
{
read(n),read(m),read(c),read(q);
while(q--)
{
memset(d1,-1,sizeof d1),memset(nxt1,0,sizeof nxt1);
memset(d2,-1,sizeof d2),memset(nxt2,0,sizeof nxt2);
scanf("%s",s1+1),init(s1,d1,nxt1);
scanf("%s",s2+1),init(s2,d2,nxt2);
memset(dp,0,sizeof dp);
int sum=1,cur=0,tx,ty,t,l=m-c+1;
dp[cur][0][0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<m;j++)
{
memset(dp[cur^1],0,sizeof dp[cur^1]);
for(int s=0;s<1<<l;s++)
for(int x=0;x<=c;x++)
for(int y=0;y<=c;y++)
if(dp[cur][s][x][y])
for(int col=0;col<3;col++)
{
tx=get(nxt1,x,col,d1);
ty=get(nxt2,y,col,d2);
if(j+1>=c)
{
t=s&(~(1<<j+1-c));
t|=(tx==c)<<j+1-c;
}
else t=s;
if(j+1>=c&&(s>>j+1-c&1)&&ty==c) continue;
add(dp[cur^1][t][tx][ty],dp[cur][s][x][y]);
}
cur^=1;
mul(sum,3);
}
for(int s=0;s<1<<l;s++)
for(int x=0;x<=c;x++)
for(int y=0;y<=c;y++)
if(x||y)
add(dp[cur][s][0][0],dp[cur][s][x][y]),dp[cur][s][x][y]=0;
}
int ans=0;
for(int s=0;s<1<<l;s++)
add(ans,dp[cur][s][0][0]);
add(sum,mod-ans);
printf("%d\n",sum);
}
return 0;
}

2019.3.6

「SCOI2016」围棋 解题报告的更多相关文章

  1. 「SCOI2016」妖怪 解题报告

    「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...

  2. 「SCOI2016」美味 解题报告

    「SCOI2016」美味 状态极差无比,一个锤子题目而已 考虑每次对\(b\)和\(d\)求\(c=d \ xor \ (a+b)\)的最大值,因为异或每一位是独立的,所以我们可以尝试按位贪心. 如果 ...

  3. 「SCOI2016」萌萌哒 解题报告

    「SCOI2016」萌萌哒 这思路厉害啊.. 容易发现有个暴力是并查集 然后我想了半天线段树优化无果 然后正解是倍增优化并查集 有这个思路就简单了,就是开一个并查集代表每个开头\(i\)每个长\(2^ ...

  4. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  5. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  6. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  7. 「HNOI2016」网络 解题报告

    「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...

  8. 「HAOI2018」染色 解题报告

    「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...

  9. 「HNOI2016」最小公倍数 解题报告

    「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...

随机推荐

  1. Java参数是值传递还是引用传递?

    先来看看参数是如何传递的. 一.参数的传递 1.基本类型的参数传递 public static void main(String[] args) { int a = 1; fun(a); } priv ...

  2. java Date时间的各种转换方式和Mysql存时间类型字段的分析

    一:各种Date之间的转换方法 public class TimeTest { public static void main(String[] args) { Date date = new Dat ...

  3. mybatis源码分析(三)------------映射文件的解析

    本篇文章主要讲解映射文件的解析过程 Mapper映射文件有哪几种配置方式呢?看下面的代码: <!-- 映射文件 --> <mappers> <!-- 通过resource ...

  4. 2017年前小纪(有关http的一些缓存理论知识)

    position的top和bottom的区别:前者基准点定在top,后者基准点定在bottom. for-in 遍历属性的顺序不确定 手机端,line-height对光标大小非常有影响 有些css3属 ...

  5. 微信小程序自定义组件

    要做自定义组件,我们先定一个小目标,比如说我们在小程序中实现一下 WEUI 中的弹窗组件,基本效果图如下. Step1 我们初始化一个小程序(本示例基础版本库为 1.7 ),删掉里面的示例代码,并新建 ...

  6. java 中Excel的导入导出

    部分转发原作者https://www.cnblogs.com/qdhxhz/p/8137282.html雨点的名字  的内容 java代码中的导入导出 首先在d盘创建一个xlsx文件,然后再进行一系列 ...

  7. Spring 配置详解

    spring4配置文件详解 一.配置数据源 基本的加载properties配置文件 <context:property-placeholder location="classpath* ...

  8. wiki 安装

    地址:https://www.jianshu.com/p/fb2574567eae

  9. redis 中主从、哨兵和集群分片模式这三个有什么区别 ?

    集群分片 比如 5主5从,也就是说 数据过来之后会均匀的分配到5台服务器上面,5台服务器上面的数据是不同的,但是每个服务器都有一个从服务器,上面的数据跟这一台主服务器的数据是一样的: 也就是说,对于这 ...

  10. hive 查询注意问题

    1)对于hive内置的列,不是自己建的,在查询的时候需要添加反引号` 比如:`_mt_message`,别在这里犯错误, (2)南京的_mt_message是json的格式,所以可以直接使用:get_ ...