这题好像比较牛逼,好像又不是怎么样。

考虑两个串是如何计算 LCS 的。

这还不简单?\(dp[n][m]=\max(\max(dp[n-1][m],dp[n][m-1]),[s[n]==t[m]]dp[n-1][m-1])\)。

我们发现一件事情:\(dp[n][m]-dp[n][m-1]\leq 1\)。

接下来引入一个叫 DP 套 DP 的神秘玩意儿。

大概其实就是在 DP 的转移 DAG(或者 DFA) 上面搞事情。

我们对 \(t\) 状压,表示当前的 \(s\) 和 \(t\) 的匹配状态。

我们如果知道匹配状态是可以直接还原 dp 数组的。我们直接还原,然后枚举 \(s\) 当前是哪一个字符,然后把转移边丢出来就好了。

以及,这个转移 DAG 包含了所有可能的边。

所有我们需要做的就是枚举当前匹配状态和下一个字符,然后把转移边丢出来。

然后转移就好了。

对于 NOI,只需要额外记录当前匹配到哪个字符,再处理一下即可。

复杂度 \(O(m2^k+k2^k)\)。

#include<cstdio>
typedef unsigned ui;
const ui mod=1e9+7;
ui n,m,lim,t[20],ans[20],ppc[1<<15],trans[1<<15|1][3],f[1<<15|1][3],g[1<<15|1][3];char s[20];
ui dp[2][20];
inline ui max(const ui&a,const ui&b){
return a>b?a:b;
}
inline void Add(ui&a,const ui&b){
if((a+=b)>=mod)a-=mod;
}
inline void init(){
lim=1<<m;
for(ui i=0;i<m;++i)t[i]=s[i]=='N'?0:s[i]=='O'?1:2;
for(ui S=0;S<lim;++S){
for(ui i=0;i<m;++i)dp[0][i]=S>>i&1;
for(ui i=1;i<m;++i)dp[0][i]+=dp[0][i-1];
for(ui s=0;s<3;++s){
dp[1][0]=dp[0][0];
if(s==t[0])dp[1][0]=1;
for(ui i=1;i<m;++i){
dp[1][i]=max(dp[1][i-1],dp[0][i]);
if(s==t[i])dp[1][i]=max(dp[1][i],dp[0][i-1]+1);
}
for(ui i=1;i<m;++i)trans[S][s]|=dp[1][i]-dp[1][i-1]<<i;trans[S][s]|=dp[1][0];
}
}
}
signed main(){
scanf("%u%u%s",&n,&m,s);init();f[0][0]=1;
for(ui i=0;i<n;++i){
for(ui S=0;S<lim;++S){
if(f[S][0]){
Add(g[trans[S][0]][1],f[S][0]);
Add(g[trans[S][1]][0],f[S][0]);
Add(g[trans[S][2]][0],f[S][0]);
}
if(f[S][1]){
Add(g[trans[S][0]][1],f[S][1]);
Add(g[trans[S][1]][2],f[S][1]);
Add(g[trans[S][2]][0],f[S][1]);
}
if(f[S][2]){
Add(g[trans[S][0]][1],f[S][2]);
Add(g[trans[S][1]][0],f[S][2]);
}
}
for(ui S=0;S<lim;++S){
f[S][0]=g[S][0];f[S][1]=g[S][1];f[S][2]=g[S][2];
g[S][0]=g[S][1]=g[S][2]=0;
}
}
for(ui S=0;S<lim;++S){
ppc[S]=ppc[S>>1]+(S&1);
for(ui i=0;i<3;++i)Add(ans[ppc[S]],f[S][i]);
}
for(ui i=0;i<=m;++i)printf("%u\n",ans[i]);
}

LGP4590题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. htc 简单的移动效果

    转载请注明来源:https://www.cnblogs.com/hookjc/ 1.创建 HTC 文件的架构.一个标准的 HTC 文件含有一个 SCRIPT 块和一对可选的 COMPONENT 标记. ...

  2. linux 进程信号

    转载请注明来源:https://www.cnblogs.com/hookjc/ signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到 ...

  3. checkstyle使用介绍

    1.我下载的是checkstyle-5.5-bin.zip:下载地址 http://sourceforge.net/projects/checkstyle/files/ 另一个是checkstyle的 ...

  4. Firewalld防火墙——基础认知

    Firewalld防火墙 1.Firewalld概述 2.firewalld与iptables 的区别 3.firewalld区域的概念 4.firewalld数据处理流程 5.firewalld检查 ...

  5. Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器,包括Spring Security和Spring Boot

    2月14日,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器. 其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队将不再提供 ...

  6. 使用grpcui测试gRPC服务

    grpcui类似Swagger UI,可以用来测试gRPC服务,使用起来特别简单. 其原理是通过自动发现gRPC服务协议(当然前提是gRPC服务暴露了Protobuf协议),然后启动一个带界面的Web ...

  7. Solution -「HNOI 2007」「洛谷 P3185」分裂游戏

    \(\mathcal{Description}\)   Link.   给定 \(n\) 堆石子,数量为 \(\{a_n\}\),双人博弈,每轮操作选定 \(i<j\le k\),使 \(a_i ...

  8. Go的优雅终止姿势

    最近优化了一版程序:用到了golang的优雅退出机制. 程序使用etcd的election sdk做高可用选主,需要在节点意外下线的时候,主动去etcd卸任(删除10s租约), 否则已经下线的节点还会 ...

  9. Java线程池进阶

    线程池是日常开发中常用的技术,使用也非常简单,不过想使用好线程池也不是件容易的事,开发者需要不断探索底层的实现原理,才能在不同的场景中选择合适的策略,最大程度发挥线程池的作用以及避免踩坑. 一.线程池 ...

  10. [Matlab]求解线性方程组

    转自:http://silencethinking.blog.163.com/blog/static/911490562008928105813169/ AX=B或XA=B在MATLAB中,求解线性方 ...