• 【LeetCode第366场周赛】8028. 执行操作使两个字符串相等 | 线性DP | 中等


    题目内容

    原题链接

    给定两个长度均为 n n n 01 01 01 字符串 s 1 s1 s1 s 2 s2 s2,以及一个正整数 x x x ,每次操作有两种选择:

    • 选择两个下标 i i i j j j ,同时反转 s 1 [ i ] s1[i] s1[i] s 1 [ j ] s1[j] s1[j] ,代价为 x x x
    • 选择一个下标 i i i 满足 i + 1 < n i+1i+1<n ,同时反转 s 1 [ i ] s1[i] s1[i] s 1 [ i + 1 ] s1[i+1] s1[i+1] ,代价为 1 1 1

    问使得 s 1 s1 s1 变为 s 2 s2 s2 的最小代价,如果不能使得 s 1 s1 s1 变为 s 2 s2 s2 ,返回 − 1 -1 1

    数据范围

    • 1 ≤ n , x ≤ 500 1\leq n,x\leq 500 1n,x500
    • s 1 s1 s1 s 2 s2 s2 均只包含字符 '0''1'

    题解

    这里 s 1 s1 s1 s 2 s2 s2 中不同的数位的数量必须为偶数,否则 s 1 s1 s1 必然无法变为 s 2 s2 s2

    考虑 f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1] 表示将 s 1 s1 s1 的前 i i i 个字符反转使得 s 1 [ 0 : i ] = s 2 [ 0 : i ] s1[0:i]=s2[0:i] s1[0:i]=s2[0:i] 的最小代价。

    其中 f [ i ] [ 1 ] f[i][1] f[i][1] 表示选择了若干次操作 1 1 1 ,最后一次操作 1 1 1 只对下标 i i i 使用了,但是未对下标 j j j 使用,就是说我有且仅有存在一次操作 1 1 1 满足只选择了下标 i i i ,还未确定下标 j j j

    状态转移

    // 第 i 位选择操作 2
    f[i][0] = min(f[i][0], f[i - 2][0] + p[i - 1] - p[i - 2]);
    f[i][1] = min(f[i][1], f[i - 2][1] + p[i - 1] - p[i - 2]);
    // 第 i 位选择操作 1
    f[i][0] = min(f[i][0], f[i - 1][1]);
    f[i][1] = min(f[i][1], f[i - 1][0] + x);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    代码

    class Solution {
    public:
        int minOperations(string s1, string s2, int x) {
            vector<int> p;
            for (int i = 0; i < s1.size(); ++i) 
                if (s1[i] != s2[i]) p.push_back(i);
            int m = p.size();
            if (m % 2 == 1) return -1;
            if (m == 0) return 0;
    
            vector<vector<int>> f(m + 1, vector<int>(2, 0x3f3f3f3f));
            f[0][0] = 0;
            f[1][1] = x;
            for (int i  = 2; i <= m; ++i) {
                // 第 i 位选择操作 2
                f[i][0] = min(f[i][0], f[i - 2][0] + p[i - 1] - p[i - 2]);
                f[i][1] = min(f[i][1], f[i - 2][1] + p[i - 1] - p[i - 2]);
                // 第 i 位选择操作 1
                f[i][0] = min(f[i][0], f[i - 1][1]);
                f[i][1] = min(f[i][1], f[i - 1][0] + x);
            }
    
            return f[m][0];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    nginx rewrite参数 以及 $1、$2参数解析(附有生产配置实例)
    大都会人寿线下培训第三天回顾(爱的书信)及线上课程笔记
    Vue实现Antv/X6中的示例,以及一些er图开发场景
    谷粒商城 高级篇 (二十四) --------- 秒杀业务
    <MySQL> 什么是数据库事务?事务该如何使用?
    skywalking实战--本地调试agent
    数据结构入门4-2(广义表、例题)
    IEEE会议论文LaTeX模板中添加页码
    webgl 系列 —— 渐变三角形
    对Java中dto、dao、service、controller层的分析
  • 原文地址:https://blog.csdn.net/weixin_43900869/article/details/133689742