[思维] aw3789. 隐藏字符串(脑筋急转弯+枚举+递推+aw周赛010_3)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[思维] aw3789. 隐藏字符串(脑筋急转弯+枚举+递推+aw周赛010_3)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:3789. 隐藏字符串

2. 题目解析

猜结论就行了。最优解一定是长度为 1 的,或者长度为 2 的子串。

因为如果长度大于 3 并且还是等差数列的话,那么长度为 1、2 的子串一定也包含在其中,所以,所以最优解一定在长度为 1、2 的子串中包含的有。

计算:

  • 长度为 1:直接遍历每个字母取出现次数最高的即可。
  • 长度为 2:前缀和 f[i][j] 统计字母 ij 出现的次数,因为仅有 26 * 26 种情况。
  • 即,假设当前枚举的是以字符 x,结尾的字符串,那么以 ax, bx, cx,...,xx, yx, zx 这 26 种情况均以 x 作为结尾,它们分别出现的次数就是 a,b,c,...,x,y,z 这些字符所出现的次数。
  • 故,仅需统计一个字符出现次数的 s 数组,和 f[26][26] 的所有长度为 2 的出现次数统计即可。
  • 注意在枚举当前位置 t 时,不要先将其计数,应该是计算完 f[][] 的所有状态之后再对其计数,s[t] ++因为以 t 结尾,那么必然 t 不能成为自己的开头,所以不能计数。

时间复杂度: O ( 26 n ) O(26n) O(26n)

空间复杂度: O ( 26 ∗ 26 ) O(26*26) O(2626)


枚举所有长度为 2 的字符串出现次数即可。

#include <bits/stdc++.h>

using namespace std;

using LL = long long;

LL s[26], f[26][26];

int main() {
    string str;
    cin >> str;
    
    LL res = 0;
    for (char i : str) {
        int t = i - 'a';
        for (int j = 0; j < 26; j ++ ) {
            f[j][t] += s[j];                    // 以t结尾的长度为2的字符串出现次数
            res = max(res, f[j][t]);            // 长度为2,更新答案
        }
        s[t] ++ ;               // 在后面累加s[t]++,枚举以自己结尾的字符串时,自己不应该加入计数中       
        res = max(res, s[t]);                   // 长度为1,更新答案
    }
    
    cout << res << endl;
    
    return 0;
}

以上是关于[思维] aw3789. 隐藏字符串(脑筋急转弯+枚举+递推+aw周赛010_3)的主要内容,如果未能解决你的问题,请参考以下文章

[思维] aw3773. 兔子跳(贪心+模拟+脑筋急转弯)

598. 范围求和 II思维 脑筋急转弯

[模拟] aw3771. 选取石子(脑筋急转弯+aw周赛008_2)

[E二分] lc852. 山脉数组的峰顶索引(二分+思维+脑筋急转弯)

跪求脑筋急转弯、智力题(要附答案的)

[构造] aw3731. 序列凑零(模拟+构造)