腾讯音乐2023笔试:可爱串


题目描述

我们定义子序列为字符串中可以不连续的一段,而子串则必须连续。例如 rderd 包含子序列 "red”,且不包含子串"red”,因此该字符串为可爱串。

小红想知道,长度为 n(3 <= n <= 10 ^ 5)的、仅由 ‘r’‘e’‘d’ 三种字母组成的字符串中,有多少是可爱串? 答案请对 10 ^ 9 + 7 取模。
在这里插入图片描述


动态规划解法

1.计算可爱串的数量:
使用动态规划数组 f、g 和 h 分别表示不同状态下的字符串数量。
f[i]:包含 “red” 子序列但不包含 “red” 子串的数量。
g[i]:包含 “re” 子序列但不包含 “red” 子串的数量。
h[i]:包含 “red” 子串的数量。
2.状态转移:
g[i] 表示长度为 i 的包含 “re” 子序列的数量。
f[i] 表示长度为 i 的包含 “red” 子序列的数量。
h[i] 表示长度为 i 的包含 “red” 子串的数量。
3.快速幂:
powMod 方法用于计算大数的幂次模。
4.输出结果:
将结果输出到标准输出。

import java.util.Scanner;

public class Main {
    private static final long MOD = 1000000007L;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读取字符串长度
        int n = sc.nextInt();

        // 计算可爱串的数量
        int result = kawaiiStrings(n);
        System.out.println(result);
    }

    public static int kawaiiStrings(int n) {
        if (n < 3) return 0; // 长度小于3时,不可能有子序列 "red"

        long[] f = new long[n + 1];
        long[] g = new long[n + 1];
        long[] h = new long[n + 1];

        // 计算g数组
        for (int i = 2; i <= n; i++) {
            g[i] = (g[i - 1] * 2 % MOD + (i - 1) * powMod(2, i - 2, MOD) % MOD) % MOD;
        }

        // 计算f数组
        for (int i = 2; i <= n; i++) {
            f[i] = (f[i - 1] * 3 % MOD + g[i - 1] % MOD) % MOD;
        }

        // 计算h数组
        for (int i = 3; i <= n; i++) {
            h[i] = (powMod(3, i - 3, MOD) + 3 * h[i - 1] % MOD + MOD - h[i - 3]) % MOD;
        }

        // 最终结果
        return (int) ((f[n] + MOD - h[n]) % MOD);
    }

    // 快速幂方法
    public static long powMod(long a, long b, long mod) {
        long res = 1;
        while (b > 0) {
            if ((b & 1) == 1) {
                res = res * a % mod;
            }
            a = a * a % mod;
            b >>= 1;
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值