「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. Linux (Redhat / Fedora / CentOS) 更改 hostname 的方式

    Linux (Redhat / Fedora / CentOS) 更改 hostname 的方式 [蔡宗融個人網站]https://www.ichiayi.com/wiki/tech/linux_ho ...

  2. 配置SQLServer,允许远程连接

    需要别人远程你的数据库,首先需要的是在一个局域网内,或者连接的是同一个路由器,接下来就是具体步骤: (一)首先是要检查SQLServer数据库服务器中是否允许远程链接.其具体操作为: (1)打开数据库 ...

  3. hadoop的缺点

    Hadoop的限制 Hadoop只能执行批量处理,并且只以顺序方式访问数据.这意味着必须搜索整个数据集,即使是最简单的搜索工作.

  4. python之路--模块和包

    一 . 模块 ⾸先,我们先看⼀个老⽣常谈的问题. 什么是模块. 模块就是⼀个包含了python定义和声明的⽂件, ⽂件名就是模块的名字加上.py后缀. 换句话说我们⽬前写的所有的py⽂件都可以看成是⼀ ...

  5. Maven 项目 无缘无故报错:版本冲突,其他机器上正常-提交的时候报冲突怎么也解决不掉

    2018年: maven突然之间报错了,显示版本冲突,但是其他的机器是好的, 使用命令:mvn compile -P dev -e; 看看测试环境有没有问题,还是有问题.而且,刚开始只是报错:erro ...

  6. qtp 自动货测试桌面程序-笔记(使用函数)

    新建-function 写入函数 rem 关闭出现错误窗口Function checkExist() If Window("出现错误").WinObject("确定&qu ...

  7. 用dbExpress页的SQLConnection1连接sql server2000怎么设置。 [问题点数:0分]

    在d7或者c6已经支持了. 贡献一下我的代码吧:dbeConn:= TSQLConnection.Create(nil);       dbeConn.Params.Clear;       dbeC ...

  8. vue表單

    使用v-model進行表單雙向數據綁定. 可以根據控件決定數據的類型,可以綁定input.單選.複選.下拉框等 可以使用number和trim等修飾符.

  9. Redis 禁用FLUSHALL FLUSHDB KEYS 命令

      (error) ERR unknown command 'keys'问题解决(error) ERR unknown command 'FLUSHDB' 问题解决 背景 FLUSHALL FLUSH ...

  10. codeforces707C

    Pythagorean Triples CodeForces - 707C 悉宇大大最近在学习三角形和勾股定理.很显然,你可以用三个边长为正数的线段去构造一个直角三角形,而这三个数被称作“勾股数”. ...