小A的咒语

给出两个字符串A,B (len<=105)

现在可以把A串拆为任意段,然后取出不超过 x 段,按在A串中的前后顺序拼接起来

问是否可以拼出B串。

【题解】

      ①如果遇上dp空间会炸,可以将那一维状态存入f[]中

      ②f[i][j]表示A串1~i位已经取出了x段,能够匹配B的最远位置的B的下标。

      ③没有后效性,因此DP是合理的:令l=lcp(A[i+1],B[dp[i][j]+1(后缀数组RMQ维护)
             dp[i+1][j]=max(dp[i+1][j],dp[i][j])  【不包含i】                   

             dp[i+l][j+1]=max(dp[i+l][j+1],dp[i][j]+l) 【包含i】

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100005
using namespace std;
char s[MAXN*2];
int sa[MAXN*2],rk[MAXN*2],ht[MAXN*2];
int dp[MAXN][105],st[MAXN*2][20],log2[MAXN*2];
void print(int n){
puts("sa:");
for(int i=0;i<n;i++) printf("%d ",sa[i]); puts("");
puts("rk:");
for(int i=0;i<n;i++) printf("%d ",rk[i]); puts("");
puts("ht:");
for(int i=0;i<n;i++) printf("%d ",ht[i]); puts("");
}
bool cmp(int *y,int len,int k,int p1,int p2){
int a=y[p1],b=y[p2];
int aa=p1+k<len?y[p1+k]:-1,bb=p2+k<len?y[p2+k]:-1;
return a==b&&aa==bb;
}
void build(int n,int m){
static int wa[MAXN*2],wb[MAXN*2],c[MAXN*2],*x,*y,p;
x=wa; y=wb;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[i]=s[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
for(int k=1;k<n;k<<=1){
p=0;
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=0;i<n;i++) if(sa[i]-k>=0) y[p++]=sa[i]-k; for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[y[i]]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; m=1; swap(x,y); x[sa[0]]=0;
for(int i=1;i<n;i++)
x[sa[i]]=cmp(y,n,k,sa[i-1],sa[i])?m-1:m++;
if(m>=n) break;
}
for(int i=0;i<n;i++) rk[sa[i]]=i;
int h=0;
for(int i=0,j;i<n;i++){
if(h) h--;
if(rk[i]!=0){
j=sa[rk[i]-1];
while(i+h<n&&j+h<n&&s[i+h]==s[j+h]) h++;
}
ht[rk[i]]=h;
}
for(int i=1;i<n;i++) st[i][0]=ht[i];
for(int k=1;(1<<k)<n;k++)
for(int i=1<<k;i<n;i++)
st[i][k]=min(st[i-(1<<(k-1))][k-1],st[i][k-1]);
}
int lcp(int i,int j){
i=rk[i]; j=rk[j];
if(i>j) swap(i,j); i++;
int k=log2[j-i+1];
return min(st[i+(1<<k)-1][k],st[j][k]);
}
int main(){
log2[1]=0;
for(int i=2;i<200000;i++) log2[i]=log2[i>>1]+1;
int T; scanf("%d",&T);
while(T--){
int n,m,x; bool fg;
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&m,&x);
scanf("%s",s); s[n]='%';
scanf("%s",s+n+1); fg=0;
build(n+m+1,301);
for(int i=-1;i<n;i++)
for(int j=0;j<=min(i+1,x);j++){
int d=i>=0?dp[i][j]:0;
if(d==m) fg=1;
dp[i+1][j]=max(dp[i+1][j],d);
int l=(i+1<n&&n+1+d<n+m+1)?lcp(i+1,n+1+d):0;
if(l==0) continue;
dp[i+l][j+1]=max(dp[i+l][j+1],d+l);
}
if(fg) printf("YES\n");
else printf("NO\n");
}
return 0;
}//*ZJ

.

【ZJ选讲·BZOJ 5073】的更多相关文章

  1. 【ZJ选讲·BZOJ 5071】

    小A的数字 有一串数字A1 ,A2,--,An,每次可以进行如下骚操作: 选择一个数字i,将(Ai-1,Ai,Ai+1)变为(Ai-1+Ai,-Ai,Ai+1+Ai), (特别地,若i=N,则( ...

  2. 【ZJ选讲·画山】

    给出一张纸(N × M),你要在上面画山,但不能画出界(N,M<=100) Like this: 起点为(0,0),终点为(N,0) 给出w种线段画法(x,y),表示用了这种画法后,笔迹末 ...

  3. 【ZJ选讲·字符串折叠】

    给一个字符串(len<=100) 把这个字符串折叠(就是压缩) 记 X(子串) 表示重复 X次该子串 比如 3(orz)  orzorzorz  来点神奇例子: AAAAAAAAAA ...

  4. 【ZJ选讲·压缩】

    给一个由小写字母组成的字符串(len<=50) 我们可以用一种简单的方法来压缩其中的重复信息. 用M,R两个大写字母表示压缩信息 M标记重复串的开始, R表示后面的一段字符串重复从上一个 ...

  5. 【ZJ选讲·调整】

    给出n个点,m条有向边(带正权),起点S,终点T.(n<=2000,m<=30000) 再给出一个k,表示可以把最多k条边的权值调整为任意非负整数.(k<=100) 问是否可以通 ...

  6. 【ZJ选讲·钻石游戏】

    N×M的棋盘(M,N<=500)中,每个格子有一个颜色(颜色数1~9) P次操作(P<=1000),每次给出两个相邻的位置(保证颜色不同,两个格子有一条公共边),把这两个格子交换. 定 ...

  7. DP选讲

    $DP$选讲直接上题吧放个题单[各省省选DP](https://www.luogu.com.cn/training/151079)$P5322[BJOI2019]$排兵布阵一眼题,考虑$dp[i][j ...

  8. PJ可能会用到的动态规划选讲-学习笔记

    PJ可能会用到的动态规划选讲-学习笔记 by Pleiades_Antares 难度和速度全部都是按照普及组来定的咯 数位状压啥就先不讲了 这里主要提到的都是比较简单的DP 一道思维数学巧题(补昨天) ...

  9. PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记

    PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...

随机推荐

  1. laravel自定义返回错误方法

    返回视图传递错误信息 function withInfoErr($msg){ return back()->with('error',$msg); } 返回视图提示消息 function wit ...

  2. java元注解(注解在注解上的注解)

    //ElementType.TYPE 给类.接口.枚举上使用 @Target(ElementType.TYPE)//给注解进行注解,表示该注解可以用在什么地方 //@Retention(Retenti ...

  3. 反向代理服务器——nginx

    一.概述 先来看百度百科的介绍: Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.其特点是占有内存少,并发能力强 ...

  4. P1196 银河英雄传说(加权并查集)

    P1196 银河英雄传说 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在 ...

  5. C语言RL78 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 前段时间完成的hype ...

  6. Ubantu修改主机名详细步骤

    使用vmWare创建的Ubantu虚拟主机,默认的主机名均为Ubantu,通过修改主机名的使得分布式集群操作变得方便.具体步骤如下: 1.查看虚拟机的主机名:打开终端,使用 hostname 命令,回 ...

  7. ArcGIS Server远程处理服务器(环境设置)

    当使用ArcGIS Server做远程处理服务器执行影像处理操作时,提示ERROR 999999通用错误代码,如下: Start Time: Mon Jul 03 13:49:06 2017Distr ...

  8. valgrind检查still reachable情况

    valgrind --leak-check=yes检查bufr编解码程序运行时提示still reachable: 568 bytes in 1 blocks,如下图示: 于是怀疑有内存泄漏,难道是m ...

  9. 【紫书】(UVa1347)Tour

    继续考虑dp题目. 题意分析 其实这里只是更加仔细的做一个lrj的复读机(Orz 他分析了一个很重要的结果:如果是一个人从左到右再回来,并且每个点恰经过一次,那么等价于两个人从左到右每个点经过一次地遍 ...

  10. 电子取证-破解给定的SAM文件

    给你一个SAM文件,如何提取出登录密码? SAM文件 ① LMHASH Administrator:500:0182bd0bd4444bf867cd839bf040d93b:c22b315c040ae ...