1 条题解

  • 0
    @ 2026-3-10 23:04:03

    题目思路与代码全解析

    一、问题核心分析

    题目要求将字符串划分为若干无重复字符的连续子串,并最大化子串价值之和(长度为ii的子串价值为aia_i)。核心难点在于:

    1. 子串必须满足「内部无重复字符」的约束;
    2. 需在满足约束的前提下,通过动态规划找到价值最大化的划分方式;
    3. 数据范围n105n \le 10^5,需注意时间复杂度优化(原代码未做极致优化,后文会补充)。

    二、动态规划(DP)核心思路

    1. DP数组定义

    定义dp[i]表示:字符串前ii个字符(s[1..i]s[1..i],代码中字符串下标从1开始)划分后的最大价值和。 目标:求dp[n](整个字符串的最大价值)。

    2. 初始状态

    dp[0] = 0:前0个字符(空串)没有子串,价值和为0。

    3. 状态转移逻辑

    对于第ii个字符,我们需要考虑所有合法的划分终点

    • 基础情况:将第ii个字符单独划分为一个子串,此时dp[i] = dp[i-1] + a[1](长度1的子串价值为a1a_1);
    • 扩展情况:从i1i-1往前找jjj1j \ge 1),若子串s[j..i]s[j..i]中无重复字符,则尝试更新dp[i] = max(dp[i], dp[j-1] + a[i-j+1])ij+1i-j+1是子串长度,对应价值aij+1a_{i-j+1});
    • 终止条件:当s[j]s[j]s[j..i]s[j..i]中重复时,停止往前找jj(因为更前面的j<jj' < j会包含重复字符,子串s[j]..is[j']..i必然不合法)。

    4. 关键优化点

    小写字母仅有26个,因此每个ii往前最多遍历26个字符就会遇到重复(无重复子串的最大长度为26)。利用这一特性,可将内层循环的时间复杂度从O(n)O(n)降为O(26)O(26),最终总时间复杂度为O(n)O(n),适配n=105n=10^5的规模。

    三、代码逐行解析

    四、样例1验证(理解执行过程)

    输入样例1

    6
    street
    2 1 7 4 3 3
    
    • 字符串:s[1]='s', s[2]='t', s[3]='r', s[4]='e', s[5]='e', s[6]='t'
    • 价值数组:a[1]=2, a[2]=1, a[3]=7, a[4]=4, a[5]=3, a[6]=3

    关键步骤计算

    i(前i个字符) 初始dp[i](单独划分) 内层j遍历(往前找合法子串) 最终dp[i]
    1 dp[0]+2=0+2=2 无(j从0开始) 2
    2 dp[1]+2=2+2=4 j=1('s'无重复):dp[0]+a[2]=1 → 4更大 4
    3 dp[2]+2=4+2=6 j=2('t'无重复):dp[1]+a[2]=3;j=1('s'无重复):dp[0]+a[3]=7 → 7更大 7
    4 dp[3]+2=7+2=9 j=3('r'无重复):dp[2]+a[2]=5;j=2('t'无重复):dp[1]+a[3]=9;j=1('s'无重复):dp[0]+a[4]=4 → 9 9
    5 dp[4]+2=9+2=11 j=4('e'重复)→ 终止循环 11
    6 dp[5]+2=11+2=13 j=5('e'无重复):dp[4]+a[2]=10;j=4('e'重复)→ 终止循环 13

    最终dp[6]=13,与样例输出一致。

    • 1

    信息

    ID
    5186
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    11
    已通过
    4
    上传者