题目描述

  $ZYB$获得了一个神秘的非空字符串$p$。
  初始时,串$S$是空的。
  $ZYB$会执行若干次这样的操作:
  $1.$选取$S$中的一个任意的位置(可以是最前面或者最后面)
  $2.$在这个位置上插入一个完整的$p$,得到一个新的$S$。
  但是$ZYB$不小心把$p$弄丢了。
  他告诉你现在的$S$是什么,请帮他还原出可能的$p$。
  如果有多个$p$符合要求,选取长度最短的。
  如果仍然有多解,选取字典序最小的。


输入格式

  从文件$string.in$中读入数据。
  这道题有多组数据,第一行一个数$T$,表示数据组数。
  对于每组数据,读入一行字符串,表示$S$。


输出格式

  输出到文件$string.out$中。
  一共$T$行,每行一个字符串$p$,表示对应的答案。


样例

样例输入:

1
hhehellolloelhellolo

样例输出:

hello


数据范围与提示

样例解释:

  $S$为:
  $1.$
  $2.hello$
  $3.hhelloello$
  $4.hhelloelhellolo$
  $5.hhehellolloelhellolo$

数据范围:

  前$20\%$:$|S|\leqslant 8$
  前$40\%$:$|S|\leqslant 20$
  前$60\%$:$|S|\leqslant 100,\sum|S|\leqslant 300$
  另有$10\%$:$S$是$p$等概率插入可行位置构造出来的。
  另有$10\%$:$p$的长度不超过$3$。
  $100\%$:$|S|\leqslant 200,T\leqslant 10,\sum|S|\leqslant 666$


题解

因为串$S$肯定有一段连续的是$p$(最后插进去的),所以可以枚举这个连续的串,再想办法判断就好了。

考虑$DP$,定义怪怪的,设$dp[l][r]$表示在当前枚举的长度为$len$的情况下,区间$[l,r]$除了前$(r-l)%len$位匹配了整串前缀以外剩下的部分都匹配了是否可行。

那么考虑转移,设$b$数组为当前$check$的这段区间:

  $\alpha.dp[l][r]|=dp[l][r-1]\&(s[j]==b[(j-i)%len+1])$:多匹配了一位。

  $\beta.dp[l][r]|=dp[i][j-k\times len]\&f[j-k\times len+1][j]$:后面有几段匹配了。

由于$\beta$转移的上界为$\frac{N}{len}$,所以最终的时间复杂度为$\Theta(\sum\limits_{len|N}(N-len+1)\times N^2\times\frac{N}{len}=\Theta(N^4)$。

不过可以对于每一个$p$,先判断一下其子集合法性,然后使用记忆化搜索即可。

时间复杂度:$\Theta(N^4)$(但是远远达不到)。

期望得分:$100$分。

实际的分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
char ch[201];
int n,a[201],b[201],ans[201];
int dp[201][201];
int mod(int x,int y){return x>y?mod(x-y,y):x;}
bool dfs(int x,int l,int r)
{
if(l>r)return 1;
if(dp[l][r]!=-1)return dp[l][r];
for(int mid=r-x;l<=mid;mid-=x)
if(dfs(x,l,mid)&&dfs(x,mid+1,r))
return dp[l][r]=1;
if(a[r]==b[mod(r-l+1,x)])return dp[l][r]=dfs(x,l,r-1);
return dp[l][r]=0;
}
bool judge(int x){for(int i=1;i<=x;i++)if(ans[i]>b[i])return 1;return 0;}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%s",ch+1);
n=strlen(ch+1);
for(int i=1;i<=n;i++)a[i]=ch[i]-'a'+1;
for(int i=1;i<=n;i++)
{
if(n%i)continue;bool res=0;
memset(ans,0,sizeof(ans));
for(int j=1;j<=n-i+1;j++)
{
memset(dp,-1,sizeof(dp));
for(int k=1;k<=i;k++)b[k]=a[j+k-1];
if(dfs(i,1,n)&&(!ans[1]||judge(i)))
for(int k=1;k<=i;k++)ans[k]=b[k];
}
if(ans[1]){for(int k=1;k<=i;k++)printf("%c",(char)(ans[k]+'a'-1));puts("");break;}
}
}
return 0;
}

rp++

[JZOJ6347]:ZYB玩字符串(DP+记忆化搜索)的更多相关文章

  1. 状压DP+记忆化搜索 UVA 1252 Twenty Questions

    题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...

  2. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+记忆化搜索

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. ...

  3. 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

    题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...

  4. 【BZOJ】1415 [Noi2005]聪聪和可可 期望DP+记忆化搜索

    [题意]给定无向图,聪聪和可可各自位于一点,可可每单位时间随机向周围走一步或停留,聪聪每单位时间追两步(先走),问追到可可的期望时间.n<=1000. [算法]期望DP+记忆化搜索 [题解]首先 ...

  5. [题解](树形dp/记忆化搜索)luogu_P1040_加分二叉树

    树形dp/记忆化搜索 首先可以看出树形dp,因为第一个问题并不需要知道子树的样子, 然而第二个输出前序遍历,必须知道每个子树的根节点,需要在树形dp过程中记录,递归输出 那么如何求最大加分树——根据中 ...

  6. poj1664 dp记忆化搜索

    http://poj.org/problem?id=1664 Description 把M个相同的苹果放在N个相同的盘子里,同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5.1.1和1 ...

  7. POJ 1088 DP=记忆化搜索

    话说DP=记忆化搜索这句话真不是虚的. 面对这道题目,题意很简单,但是DP的时候,方向分为四个,这个时候用递推就好难写了,你很难得到当前状态的前一个真实状态,这个时候记忆化搜索就派上用场啦! 通过对四 ...

  8. loj 1044(dp+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26764 思路:dp[pos]表示0-pos这段字符串最少分割的回文 ...

  9. SDUT 2893-B(DP || 记忆化搜索)

    B Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 有n块地板排成一条直线,从左到右编号为1,2,3. . . n-1,n,每 ...

随机推荐

  1. C++string类字符串学习

    1.逆转字符串 第一种,使用algorithm中reverse函数. #include <algorithm> #include <string> #include <i ...

  2. 1 bootstrapValidator使用

    1 如何使用 引入 <link href="bootstrapValidator.min.css" rel="stylesheet"> css文件 ...

  3. property配置

    之前把设备历史数据存储的时间周期存储在了数据库中,因为以下一些原因,我打算改写到property配置文件中 1.这个周期时间的配置没有单独放一个tabel中,导致现在设备类型越来越多,每次添加或者修改 ...

  4. 第四章、前端之BOM和DOM

    目录 第四章.前端之BOM和DOM 一.解释BOM和DOM 二.window对象 三.window子对象 四.弹出框 五.计时相关 六.HTML的DOM树 七.查找元素 八.节点操作 九.JS操作CS ...

  5. Hadoop_20_MapReduce程序的运行模式

    1.MapReduce程序的运行模式 1. Windows中运行MapReduce程序 (1)mapreduce程序是被提交给LocalJobRunner在本地以单进程的形式运行 (2)而处理的数据及 ...

  6. oracle 初试 hint

    最近在研究oracle的视图问题,本来想全转成 物化视图(materialized view)的,这样可以极大提升系统的响应时间,无奈工作量太大,所以就研究了SQL优化的问题. 我这个普通视图 有36 ...

  7. css网页使用自定义字体方法

    @font-face可以加载服务器端的字体到浏览器端,这样设计师就可以不受客户端字体库的限制. 一般来说有四种格式的字体文件即可覆盖所有浏览器.这四种格式为: .EOT:适用于Internet Exp ...

  8. http方式获取远程文件内容

    public class HttpServer { /// <summary> /// 读取远程文件的内容 /// </summary> /// <param name= ...

  9. ECMAScript 6 入门——ES6 声明变量的六种方法

    ES6 声明变量的六种方法 ES5 只有两种声明变量的方法:var命令和function命令.ES6 除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和cla ...

  10. MyBatis-09-Lombok

    9.Lombok Project Lombok is a java library that automatically plugs into your editor and build tools, ...