DP-Leetcode 奇怪的打印机

这篇博客讨论了LeetCode中的664题——奇怪的打印机。通过使用动态规划(DP)方法解决该问题,博主分析了状态表示、状态转移方程以及C++代码实现。文章介绍了如何以字符串的子串为单位,逐步计算最少打印次数,最终得出整个字符串的最少打印次数。
摘要由CSDN通过智能技术生成

题目链接: Leetcode 664. 奇怪的打印机

题目: 奇怪的打印机
题目描述

有台奇怪的打印机有以下两个特殊要求:

  • 打印机每次只能打印由 同一个字符 组成的序列。
  • 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。

给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数。

样例
示例1 : 
输入:s = "aaabbb"
输出:2
解释:首先打印 "aaa" 然后打印 "bbb"。

示例2 : 
输入:s = "aba"
输出:2
解释:首先打印 "aaa" 然后在第二个位置打印 "b" 覆盖掉原来的字符 'a'
提示
  • 1 ≤ \le s.length ≤ \le 100
  • s 由小写英文字母组成

算法1 (Dp动态规划)
思路分析

奇怪的打印机, 一拿到手就感觉应该用dp来考虑问题, 考虑状态表示的维度, 首先一维的话表示的就是f(i) 以字符串s[i]结尾的串打印的最少次数, 那么状态转移方程并不好写, 故考虑两维的状态表示, 两维的话f(i, j)表示的话打印s[i ~ j] 区间的最少打印次数. DP问题用闫氏DP法分析:

在这里插入图片描述

时间复杂度 O ( n 3 ) O(n^3) O(n3)

区间DP问题, 状态计算 n 2 n^2 n2的复杂度, 状态转移方程复杂度为n, 故总共的时间复杂度为 O ( n 3 ) O(n^3) O(n3)

C++ 代码
class Solution
{
public:
    static constexpr int N = 101;
    int f[N][N]; 
    int strangePrinter(string s) 
    {
        memset(f, 0, sizeof f); 

        int n = s.size(); 
        for(int len = 1; len <= n; ++len)
        {
            for(int i = 0; i + len - 1 < n; ++i)
            {
                int j = i + len - 1;
                f[i][j] = f[i + 1][j] + 1; 
                for(int k = i + 1; k <= j; ++k) 
                    if(s[i] == s[k]) f[i][j] = min(f[i][j], f[i][k - 1] + f[k + 1][j]);
            }
        }
        
        return f[0][n - 1]; 
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值