【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 s1i s1i 和 s 1 j s1j s1j ,代价为 x x x
  • 选择一个下标 i i i 满足 i + 1 < n i+1<n i+1<n ,同时反转 s 1 i s1i s1i 和 s 1 i + 1 s1i+1 s1i+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 1≤n,x≤500
  • 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 fi0/1 fi0/1 表示将 s 1 s1 s1 的前 i i i 个字符反转使得 s 1 0 : i = s 2 0 : i s10:i=s20:i s10:i=s20:i 的最小代价。

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

状态转移:

cpp 复制代码
// 第 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);

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

代码

cpp 复制代码
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];
    }
};
相关推荐
Pniubi28 分钟前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
꧁细听勿语情꧂1 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
文丑颜不良啊1 小时前
LeetCode2741~2760题目解析
java·leetcode
俊俊几年的2 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c
小雉系统11 小时前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构
唐墨12315 小时前
linux kernel 比较数据大小的宏定义
linux·算法
拂拉氏15 小时前
【知识讲解-题目讲解】 统计满足K约束的子字符串数量2 (滑动窗口+前缀和+二分查找+分析)
算法·前缀和·二分查找·滑动窗口
lsc_blog19 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
通信小呆呆20 小时前
电子战抗干扰技术:当“不被干扰”成为一种系统
算法·通信·mimo·isac