算法:dp+字典树

题目链接Ann and Half-Palindrome

  在CF刷字符串题的时候遇到了这题,其实并没有黑题这么难,个人感觉最多是紫题吧(虽然一开始以为是后缀自动机的神仙题)。

  首先注意到字符串 \(s\) 长度很小( \(1\le|s|\le5000\) ),可以 \(\mathcal O(n^2)\) 地把所有子串求出来,再用Trie树存起来,这样就方便我们dfs求字典序第 \(k\) 小的半回文串。所以问题重心变为怎么快速判断这些子串是否为半回文串。根据半回文串的特点,长度长的半回文串是包含长度小的半回文串的,所以我们可以用区间dp解决。设 \(f[i][l]\) 表示 \(s[i,i+l-1]\) 是否为半回文串,它的转移方程可以写作( \([A]\) 表示 \(A\) 为真时值为1,否则为0):

\[\left\{\begin{array}{l}f[i][1]=1\\ f[i][2]=[s[i]=s[i+1]]\\f[i][3]=[s[i]=s[i+2]]\\f[i][4]=[s[i]=s[i+3]] \\ f[i][l]~=[~s[i]=s[i+l-1]\&\&f[i+2][l-4]~],l\ge5\end{array}\right.
\]

  这样dp的时间复杂度也是 \(\mathcal O(n^2)\) 的。之后dfs求解第 \(k\) 小的半回文串就比较简单了,由于Trie节点数也是 \(\mathcal O(n^2)\) 的,所以总时间复杂度是 \(\mathcal O(n^2)\) 的。

\(Code:\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e3 + 5;
bool f[N][N];
int trie[N * N][2],cnt,num[N * N],tot,k;
char s[N+6],ans[N]; void dfs(int now){
for(int i = 0;i <= 1;i++){
int next = trie[now][i];
if(next == 0) continue;
//如果该节点所表示的半回文串数量大于k,说明答案就是该半回文串。
if(k <= num[next]) {
ans[++tot] = i + 'a';
for(int j = 1; j <= tot; j++) printf("%c", ans[j]);
exit(0);
}
k -= num[next]; //k为全局变量
ans[++tot] = i + 'a';
dfs(next);
tot--;
}
} int main() {
scanf("%s %d",s+1,&k);
int len = strlen(s+1);
for(int i = 1;i <=len;i++) f[i][1] = 1;
for(int i = 1;i < len;i++) f[i][2] = s[i] == s[i+1];
for(int i = 1;i < len;i++) f[i][3] = s[i] == s[i+2];
for(int i = 1;i < len;i++) f[i][4] = s[i] == s[i+3];
for(int l = 5;l <= len;l++)
for(int i = 1; i <= len; i++)
f[i][l] = (s[i] == s[i+l-1] && f[i+2][l-4]);
//将s所有子串加入trie树中
for(int i = 1;i <= len;i++){
int now = 0;
for(int l = 1; l+i-1 <= len; l++){
int c = s[i+l-1] - 'a';
if(trie[now][c] == 0) trie[now][c] = ++cnt;
now = trie[now][c];
if(f[i][l]) num[now]++;
}
}
dfs(0);
return 0;
}

CF557E Ann and Half-Palindrome 题解的更多相关文章

  1. POJ3974:Palindrome——题解

    http://poj.org/problem?id=3974 题目大意: 求最大回文子串长度. ———————————————————— 马拉车板子题. 马拉车大概讲解: 首先在每两个字母之间插入‘# ...

  2. URAL1297:Palindrome——题解

    http://acm.timus.ru/problem.aspx?space=1&num=1297 https://vjudge.net/problem/URAL-1297 给定一个字符串,求 ...

  3. CF557E Ann and Half-Palindrome 字典树+dp

    现在看这道题也不难啊,不知道考场上为啥没切~ code: #include <bits/stdc++.h> #define N 5006 #define setIO(s) freopen( ...

  4. Valid Palindrome leetcode java

    题目: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ig ...

  5. 【leetcode刷题笔记】Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  6. Leetcode 9. Palindrome Number(水)

    9. Palindrome Number Easy Determine whether an integer is a palindrome. An integer is a palindrome w ...

  7. 2013-2014集训之DP

    第一周: 经过漫长的时间,终于有时间来写一下结题报告. 地址http://acm.hust.edu.cn/vjudge/contest/view.action?cid=36180#overview A ...

  8. A. Karen and Morning

    A. Karen and Morning time limit per test 2 seconds  memory limit per test 512 megabytes input standa ...

  9. [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总

    本文出自   http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner  打开 这个专题一共有25题,刷完 ...

随机推荐

  1. oslab oranges 一个操作系统的实现 实验四 认识保护模式(三):中断异常

    实验目的: 理解中断与异常机制的实现机理 对应章节:第三章3.4节,3.5节 实验内容: 1. 理解中断与异常的机制 2. 调试8259A的编程基本例程 3. 调试时钟中断例程 4. 建立IDT,实现 ...

  2. sscanf的最基础用法(非原创)

    1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 int main(){ 6 ch ...

  3. HDU 4866 Shooting(主席树)题解

    题意:在一个射击游戏里面,游戏者可以选择地面上[1,X]的一个点射击,并且可以在这个点垂直向上射击最近的K个目标,每个目标有一个价值,价值等于它到地面的距离.游戏中有N个目标,每个目标从L覆盖到R,距 ...

  4. matplotlib 单figure多图

    method 1 import numpy as np import matplotlib.pyplot as plt fg, axes = plt.subplots(1, 2, figsize=(1 ...

  5. back to top & back to bottom

    back to top & back to bottom infinite auto load more & infinite scroll & load more https ...

  6. SVG namespace & preview bug

    SVG namespace & preview bug error This XML file does not appear to have any style information as ...

  7. python 第三方库paramiko

    目录 介绍 三种常用方式 使用密码进行登录 使用密钥免密码登录 SFTP 传输文件 terminal demo 介绍 paramiko是什么可以参考其他人的博客或文章,这里不再赘述,直入正题. 本次测 ...

  8. django学习-21.优化表数据的标题展示

    目录结构 1.前言 2.表数据的标题默认展示的数据格式是[模型类名 object(主键名)]的相关信息 3.优化表数据的标题展示的数据格式是[改成我们想要展示的数据格式]的相关完整操作步骤 3.1.第 ...

  9. scala:函数作为值或参数进行传递、作为返回值进行返回

    @ 目录 函数可以作为值进行传递 函数可以作为参数进行传递 函数可以作为返回值进行返回 什么是匿名函数 函数可以作为值进行传递 语法var f = 函数名 _ 如果明确了变量的数据类型,那么下划线可以 ...

  10. 解决java POI导入Excel超时问题

    由于要导入大量数据,后台会耗费很长时间,导致超时. 本项目前端request.js中设定的超时时间为150s. const service = axios.create({ baseURL: base ...