903. [CSP2019 提高级] 第 31 题

[CSP2019 提高级] 第 31 题

tt 是 ss 的子序列的意思是:从 ss 中删去若干个字符,可以得到 tt;特别的,如果 s=ts=t,那么 tt 也是 ss 的子序列;空串是任何串的子序列。例如:acd\texttt{acd} 是 abcde\texttt{abcde} 的子序列,acd\texttt{acd} 是 acd\texttt{acd} 的子序列,但 adc\texttt{adc} 不是 abcde\texttt{abcde} 的子序列。

s[x..y]s[x..y] 表示 s[x]⋯s[y]s[x] \cdots s[y] 共 y−x+ly-x+l 个字符构成的字符串,若 x>yx>y 则 s[x..y]s[x..y] 是空串。t[x..y]t[x..y] 同理。

#include <iostream>
#include <string>
using namespace std;
const int max1 = 202;
string s, t;
int pre[max1], suf[max1];

int main() {
    cin >> s >> t;
    int slen = s.length(), tlen = t.length();

    for (int i = 0, j = 0; i < slen; ++i) {
        if (j < tlen && s[i] == t[j]) ++j;
        pre[i] = j; // t[0..j-1] 是 s[0..i] 的子序列
    }

    for (int  i = slen - 1 , j = tlen - 1; i >= 0; --i) {
        if(j >= 0 && s[i] == t [j]) --j;
        suf[i]= j; // t[j+1..tlen-1] 是 s[i..slen-1] 的子序列
    }

    suf[slen] = tlen -1;
    int ans = 0;
    for (int i = 0, j = 0, tmp = 0; i <= slen; ++i){
        while(j <= slen && tmp >= suf[j] + 1) ++j;
        ans = max(ans, j - i - 1);
        tmp = pre[i];
    }
    cout << ans << endl;
    return 0;
}

提示:

  • t[0…pre[i]−1]t[0\dots pre[i]-1] 是 s[0…i]s[0\dots i] 的子序列;
  • t[suf[i]+1…tlen−1]t[suf[i]+1\dots tlen-1] 是 s[i…slen−1] s[i\dots slen-1] 的子序列。

(22 分)当 tt 是 ss 的子序列时,pre 数组和 suf 数组满足:对任意 0≤i<slen,pre[i]>suf[i+1]+10 \leq i < slen, pre[i] > suf[i + 1] + 1。 ( )

{{ select(1) }}

  • 正确
  • 错误