LeeCode 664. Strange Printer

特殊打印机输出算法
本文介绍了一种特殊打印机的输出算法,旨在找到输出特定字符串所需的最少打印次数。通过动态规划的方法,将问题分解并求解最优解。

题意

有一个特殊的printer,每次可以从任意位置输出任意长度相同字符,但是会覆盖之前的输出,现在给一个字符串,问需要最少多少次能输出这个字符串。

题解

对于一个字符串:

  1. 直接分成前后两部分输出
  2. 如果首尾字符相同,那么可以先输出整个字符串长度的首字符。然后再输出中间的字符。

那么另dp[i][j]dp[i][j]表示输出i到j这一部分的字符串需要的最少次数,那么:

  1. dp[i][j]=mink(dp[i][k]+d[k+1][j])dp[i][j]=mink(dp[i][k]+d[k+1][j])
  2. dp[i][j]=mink(dp[i][k]+d[k][j]1),when s[i]==s[k]==s[j]dp[i][j]=mink(dp[i][k]+d[k][j]−1),when s[i]==s[k]==s[j]

最后dp[i][j]dp[i][j]取1、2的最小值就行,用记忆化搜索来做。

代码

class Solution {
public:
    int strangePrinter(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), -1));
        return dfs(0, s.size() - 1, dp, s);
    }
    int dfs(int st, int ed, vector<vector<int>> &dp, string  &s) {
        if (st == ed) {
            return 1;
        }
        if (st > ed) {
            return 0;
        }
        if (st + 1 == ed && s[st] == s[ed]) {
            return 1;
        }
        if (dp[st][ed] != -1) {
            return dp[st][ed];
        }
        int ans = 1e8;
        for (int i = st; i < ed; i++) {
            ans = min(ans, dfs(st, i, dp, s) + dfs(i + 1, ed, dp, s));
        }
        if (s[st] == s[ed]) {
            ans = min(ans, dfs(st + 1, ed - 1, dp, s) + 1);
            for (int i = st + 1; i < ed; i++) {
                if (s[i] == s[st]) {
                    ans = min(ans, dfs(st, i, dp, s) + dfs(i, ed, dp, s) - 1);
                }
            }
        }
        return dp[st][ed] = ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值