算法: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. 大数据开发-Spark-初识Spark-Graph && 快速入门

    1.Spark Graph简介 GraphX 是 Spark 一个组件,专门用来表示图以及进行图的并行计算.GraphX 通过重新定义了图的抽象概念来拓展了 RDD: 定向多图,其属性附加到每个顶点和 ...

  2. OPENSOURCE - libcurl

    本文仅做备份存档,原文地址如下,请点链接进入 https://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html https://www.c ...

  3. 在程序中通过Process启动外部exe的方法及注意事项

    启动外部进程的方法: /// <summary> /// 启动外部进程 /// </summary> /// <param name="path"&g ...

  4. JavaScript DOM操作之查找元素节点

    概要: 编程接口 可通过 JavaScript 对 HTML DOM 进行访问. 所有 HTML 元素被定义为对象,而编程接口则是对象方法和对象属性. 方法是您能够执行的动作(比如添加或修改元素). ...

  5. 2019牛客多校第六场H Pair(数位DP 多个数相关)题解

    题意: 传送门 给你\(A,B,C\),要求你给出有多少对\((x, y)\)满足\(x\in [1,A],y\in [1,B]\),且满足以下任意一个条件:\(x \& y > C\) ...

  6. 在利用手背扫描图像+K因子 对室内温度进行回归预测时碰到的问题

    1. 关于多输入流: 由于本Mission是双输入, 导师要求尽量能使用Inception之诸, 于是输入便成了问题. 思考: 在Github上找到了keras-inceptionV4进行对网络头尾的 ...

  7. CVS、SVN、Git、GitHub :版本控制系统

    1 1 1 Git常用命令 1 1 1 1 1 1 https://www.codecademy.com/learn/learn-git Learn Git You have now been int ...

  8. 如何将多个 Apple 设备中保存在 iCloud 里面密码同步

    如何将多个 Apple 设备中保存在 iCloud 里面密码同步 iCloud 钥匙串 密码同步 数据迁移 iOS iCloud 钥匙串会记住一些信息,因此您就无需记忆这些信息. 它会在您批准的任何设 ...

  9. HTML marquee

    HTML marquee 跑马灯 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/marquee https://developer ...

  10. vue SSR & asyncData & nuxt.js

    vue SSR & asyncData & nuxt.js https://zh.nuxtjs.org/api/ https://www.cnblogs.com/xgqfrms/p/1 ...