题解:小蒟蒻的子序列
Posted zymmyz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解:小蒟蒻的子序列相关的知识,希望对你有一定的参考价值。
题目描述
小蒟蒻最近对字符串的子序列着了迷。一个字符串 s 被称作另一个字符串 S 的子序列,说明从序列 S 去除某些元素但不破坏余下元素的相对位置(在前或在后)可得到序列 s 。
小蒟蒻想到了如下的问题:给出一个由’a’, ’b’, ’c’ 组成的长度为 n 的字符串。
定义一个子序列 T 的价值如下:若子序列 T存在循环节,则其价值为 (lenT)^2 / cT ,其中 lenT 表示 T 的长度,cT 表示 T 的最小循环节长度;
反之若 T 不存在循环节,则其价值为 0。 找出价值最大的子序列所具有的价值。
何谓循环节?若长度为 x 的字符串 A 具有循环节,则代表存在长度为 y 的字符串B,x % y = 0,且A恰好是由 x / y 个 B首尾相连组合而成的。
当 y 最小时,B称为 A 的最小循环节。
这可难倒了小蒟蒻,你能帮帮他吗?
输入格式
输入的第一行包括一个整数 n(1 ≤n≤ 10000),表示字符串的长度。
输入的第二行包括一个长为 n 的字符串,其组成元素只有’a’, ’b’, ’c’。
输出格式
输出包括一行一个元素ans,表示价值最大的子序列所具有的价值。分
样例输入
3
abc
样例输出
3
由抽屉原理易知,对于一个只由‘a‘,‘b‘,‘c‘组成的字符串,至少有一种字符的数量>= n/3。那么不妨设‘a‘的数量>= n/3,我们可以考虑去掉所有的‘b‘和‘c‘,得到一个只由‘a‘组成的子序列。由公式 (lenT)^2 / cT知, 该子序列的价值 >= n^2/9。知道了该子序列的价值有什么用呢?根据题意,我们需要找的是最大价值的子序列,现在已经证明存在一个子序列的价值 >= n^2/9,那么目标子序列的价值一定也 >= n^/9。
易知,最终得到的子序列的长度 lenT <= n。
综合以上两个结论,我们可以得到 ans = (lenT)^2 / cT >= n^2 / 9 和 lenT <= n,由此便可推导出cT <= 9,易知以上两个式子不可同时取得等号,故cT < 9。
有了cT < 9,这道题就变成了一道简单的dfs。首先我们生成所有长度小于9的简单循环节。(简单循环节即该字符串有且仅有唯一的循环节为其本身)
1 for (int i = 1; i <= min(8, n); i++) { 2 dfs(0, i); 3 } 4 5 void dfs(int step, int len) { 6 if (step == len) { 7 xhj[len] = ‘