蓝桥 区间dp
发布日期:2021-05-14 16:48:37 浏览次数:16 分类:精选文章

本文共 1216 字,大约阅读时间需要 4 分钟。

为了解决这个问题,我们需要计算从对称状态变成现在状态所至少脱落的种子数。我们可以通过动态规划的方法来找到最长对称子序列,然后计算脱落的种子数。

方法思路

  • 问题分析:给定一个由A、B、C、D四种种子组成的密码串,我们需要找到至少脱落多少个种子才能使其变成现在的状态。这个问题可以转化为寻找最长对称子序列的问题。
  • 动态规划:我们可以使用动态规划来解决这个问题。定义一个二维数组dp[i][j],表示从位置i到j的子串的最长对称子序列的长度。
  • 状态转移
    • 如果s[i] == s[j],那么最长对称子序列的长度是dp[i+1][j-1] + 2
    • 如果s[i] != s[j],那么最长对称子序列的长度是max(dp[i][j-1], dp[i+1][j])
  • 结果计算:最长对称子序列的长度减去原串长度,即为脱落的种子数。
  • 解决代码

    #include 
    #include
    using namespace std;
    int main() {
    string s;
    int n;
    scanf("%s", s.c_str());
    n = s.size();
    if (n == 0) {
    return 0;
    }
    int dp[n][n];
    for (int i = 0; i < n; ++i) {
    dp[i][i] = 1;
    }
    for (int l = 2; l <= n; ++l) {
    for (int i = 0; i <= n - l; ++i) {
    int j = i + l - 1;
    if (s[i] == s[j]) {
    dp[i][j] = 2 + dp[i + 1][j - 1];
    } else {
    dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
    }
    }
    }
    int max_len = dp[0][n-1];
    int result = n - max_len;
    cout << result << endl;
    return 0;
    }

    代码解释

  • 输入处理:读取输入字符串并获取其长度。
  • 初始化:创建一个二维数组dp,其中dp[i][i]初始化为1,因为一个单独的字符本身就是最长对称子序列。
  • 填充dp数组:从长度2开始,逐步增加,计算每个子串的最长对称子序列长度。
  • 计算结果:最长对称子序列的长度减去原串长度,得到至少脱落的种子数。
  • 通过这种方法,我们可以高效地解决问题,并确保结果的正确性。

    上一篇:最小生成树 acwing1146. 新的开始
    下一篇:蓝桥训练:找最大环

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年04月22日 14时58分18秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章