题面

一个长度为 \(k\) 字符串序列 \(s\) 是好的,当且仅当 \(\forall 1\le i<k\),有 \(B_i\) 既是 \(B_{i+1}\) 的前缀,又是 \(B_{i+1}\) 的后缀 .

给一个字符串序列 \(A\),求其最长好子序列 .


数据范围:\(\displaystyle \sum_k |A_k|\le 2\times 10^6\)

时限 \(2\ \rm s\),空限 \(512\rm\ MB\) .

题解

算法 1

考虑 dp .

令 \(dp_i\) 表示以 \(A_i\) 结尾的最长好序列,于是可以暴力转移 .

时间复杂度 \(O(n^3)\),期望 \(20\sim 40pts\) .

算法 2

考虑加速算法 \(1\) 中转移过程 .

字符串 Hash 处理每个子串的 border,同时构建映射 \(\mathrm M:\,border\to dp\) .

一轮 dp 可以线性完成,映射可以考虑两种实现方式

方式编号 表现 \(1\) 表现 \(2\) 时间复杂度
\(1\) std::map 平衡树 \(O(n\log n)\)
\(2\) std::unordered_map Hash Table \(O(n)\)

期望 \(100pts\) .

算法 3(标答)

记 \(\overline s\) 为 \(s\) 逆序排成的字符串 .

于是 \(s\) 是 \(t\) 的后缀等价于 \(\overline s\) 是 \(\overline t\) 的前缀 .

现在我们有两个前缀关系,建 Trie 树并且在 Trie 树上 dp 即可 .

期望 \(100pts\) .

代码

算法 1

20pts(by jijidawang)

using namespace std;
typedef long long ll;
const int N = 1e6 + 500;
int n;
ll p, dp[N];
string s[N];
inline bool pure_chk(string a, string b)
{
int la = a.length(), lb = b.length();
if (la > lb) return false;
for (int i=0; i<la; i++)
if (a[i] != b[i]) return false;
return true;
}
inline bool chk(string a, string b)
{
bool ans = pure_chk(a, b);
reverse(b.begin(), b.end());
return ans & pure_chk(a, b);
}
int main()
{
scanf("%d", &n);
for (int i=1; i<=n; i++) cin >> s[i];
dp[1] = 1;
for (int i=2; i<=n; i++)
for (int j=1; j<i; j++)
if (chk(s[j], s[i])) dp[i] = max(dp[i], dp[j]+1);
ll ans = 0;
for (int i=1; i<=n; i++) ans = max(ans, dp[i]);
printf("%lld\n", ans);
return 0;
}

40pts(by Rolling_Star)

using namespace std;

int n,dp[2000001];
string s[2000001];
bool flag;
inline bool check(int x,int y); int main()
{
cin>>n;
for(register int i=1;i<=n;i++)
cin>>s[i];
int ans=0;
dp[1]=1;
for(register int i=2;i<=n;++i)
{
dp[i]=1;
for(register int j=1;j<=i-1;++j)
if(s[i].size()>=s[j].size())
if(check(i,j))
dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
cout<<ans;
} inline bool check(int x,int y)
{
for(register int i=0;i<s[y].size();++i)
if(s[y][i]!=s[x][i])
return false;
for(register int i=s[x].size()-s[y].size(),j=0;j<s[y].size();++i,++j)
if(s[y][j]!=s[x][i])
return false;
return true;
}

算法 2

using namespace std;
const int N = 1e6 + 500;
typedef long long ll;
typedef char str[N];
const ll P = 1e9+7, base = 131;
int n;
ll pb[N];
str s;
map<ll, int> dp;
int main()
{
scanf("%d", &n);
pb[0] = 1;
for (int i=1; i<N; i++) pb[i] = pb[i-1] * base % P;
int ans = 0;
for (int i=1; i<=n; i++)
{
scanf("%s", s+1); int l = strlen(s+1);
ll p=0, ss=0; int H=0;
for (int j=1; j<=l; j++)
{
p = (p*base % P + s[j]) % P;
ss = (ss + s[l-j+1]*pb[j-1] % P) % P;
if (p == ss) H = max(H, dp[p]);
}
dp[p] = max(dp[p], H+1);
ans = max(ans, dp[p]);
} printf("%d\n", ans);
return 0;
}

算法 3

Pref 社论的更多相关文章

  1. @ConfigurationProperties(pref="")加载局部配置文件

    刚开始@ConfigurationProperties(文件名)直接在参数里加文件名,其实是配置前缀pref="前缀".加载局部配置文件是@PropertySource(value ...

  2. Chrome Switchs & Chrome Pref

    Chrome Switchs: https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_switche ...

  3. 丽泽普及2022交流赛day20 1/4社论

    目录 T1 正方形 T2 玩蛇 T3 嗷呜 T4 开车 T1 正方形 略 T2 玩蛇 略 T3 嗷呜 (插一个删一个?) 找出相同的,丢掉循环节 . 感觉非常离谱,,, 正确性存疑 正确性问 SoyT ...

  4. Minimax 社论

    目录 题面 题解 代码 Reference 题面 LOJ #2537 / 洛谷 P5298 「PKUWC2018」Minimax 一棵有根二叉树 \(\mathcal T\) . 定义结点 \(x\) ...

  5. 丽泽普及2022交流赛day22 无社论

    开始掉分模式 . T3 有人上费用流了???(id) 不用 TOC 了 . T1 暴力 T2 没看见 任意两圆不相交,gg 包含关系容易维护,特判相切 . 单调栈即可 T3 贪心 T4 神秘题

  6. 丽泽普及2022交流赛day21 社论

    A 暴力 . greater<double> -> greater<int> \(100\) -> \(50\) 代码丢了 . B dp . 考场上代码抢救一下就过 ...

  7. 丽泽普及2022交流赛day19 半社论

    目录 No Problem Str Not TSP 题面 题解 代码 Game 题面 题解 代码 No Problem 暴力 Str 存在循环节,大力找出来即可,长度显然不超过 \(10^3\) . ...

  8. 丽泽普及2022交流赛day18 社论

    A 暴力扫一遍 B 算法 0 似乎是二分 算法 1 随便贪心 C 算法 1 枚举一个点作为最大值 / 最小值,用单调栈维护其作为答案的左右端点即可轻易计算 . 时间复杂度 \(O(n)\) . 算法 ...

  9. 膜 社论(egg drop)

    题面 \(n\) 楼 \(m\) 个鸡蛋,从 \(k\) 楼及以上扔下去会碎,不能再测试 . 问至少需要扔几次确定 \(k\) . \(n\le 10^{18}\),\(m\le 64\) . 题解 ...

随机推荐

  1. mySql in 语句查询优化

    有这么一条sql UPDATE product set BuyerCount =BuyerCount+1 where ProductId in( SELECT ProductId from order ...

  2. zabbix 1.1

    1.zabbix监控平台 2.zabbix的三部分组件:      Zabbix server 是 Zabbix软件的核心组件,agent 向其报告可用性.系统完整性信息和统计信息.server也是存 ...

  3. Python 中的内存管理

    Python 中一切皆对象,这些对象的内存都是在运行时动态地在堆中进行分配的,就连 Python 虚拟机使用的栈也是在堆上模拟的.既然一切皆对象,那么在 Python 程序运行过程中对象的创建和释放就 ...

  4. There appears to be trouble with your network connection. Retrying…

    yarn 错误There appears to be trouble with your network connection. Retrying- 原因:yarn超时 解决途径: #查看代理 yar ...

  5. 第24章 Java 数据类型转换

    每日一句 井底点灯深烛伊,共郎长行莫围棋. 每日一句 What we call "failure" is not falling down, but the staying dow ...

  6. 3. Docker应用

  7. 分享一个基于 netty 的 java 开源项目

    1.简介 中微子代理(neutrino-proxy)是一个基于 netty 的.开源的 java 内网穿透项目.遵循 MIT 许可,因此您可以对它进行复制.修改.传播并用于任何个人或商业行为. 2.项 ...

  8. 开始讨论离散型随机变量吧!《考研概率论学习之我见》 -by zobol

    上一文中,笔者给出了随机变量的基本定义:一个可测映射,从结果空间到实数集,我们的目的是为了引入函数这个数学工具到考研概率论中,但是我们在现实中面对的一些事情结果,映射而成的随机变量和其对应的概率值,并 ...

  9. 基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制

    字段的权限控制,一般就是控制对应角色人员对某个业务对象的一些敏感字段的可访问性:包括可见.可编辑性等处理.本篇随笔结合基于SqlSugar的开发框架进行的字段控制管理介绍. 在设计字段权限的时候,我们 ...

  10. 几百行代码实现一个 JSON 解析器

    前言 之前在写 gscript时我就在想有没有利用编译原理实现一个更实际工具?毕竟真写一个语言的难度不低,并且也很难真的应用起来. 一次无意间看到有人提起 JSON 解析器,这类工具充斥着我们的日常开 ...