奇怪的打印机问题(最小打印次数问题进阶版)
字数 1360 2025-11-17 20:50:42
奇怪的打印机问题(最小打印次数问题进阶版)
题目描述:
有一个奇怪的打印机,它每次打印时可以选择任意起始和结束位置,将这段区间内的所有字符打印成同一个字符。每次打印操作会覆盖之前同一位置上的字符。现在给定一个字符串s,你需要找出打印出这个字符串所需的最少打印次数。
解题过程:
让我们用"aabbac"这个例子来说明解题思路:
- 问题分析:
- 打印机可以一次打印一段连续区间为同一个字符
- 后打印的会覆盖先打印的
- 目标是找到最少的打印次数
-
状态定义:
定义dp[i][j]表示打印出子串s[i...j]所需的最少打印次数。 -
基础情况:
- 当i = j时,dp[i][j] = 1(单个字符只需要打印一次)
- 当i > j时,dp[i][j] = 0(空子串不需要打印)
- 状态转移方程:
情况1:如果s[i] == s[j]
我们可以考虑在打印s[i]时一次性把s[j]也打印出来,这样可以节省一次操作:
dp[i][j] = min(dp[i][j-1], dp[i+1][j])
情况2:如果s[i] != s[j]
我们需要将区间分割成两部分分别处理:
dp[i][j] = min(dp[i][k] + dp[k+1][j]),其中i ≤ k < j
- 详细推导过程:
以"aabbac"为例:
首先填充基础情况:
- dp[0][0] = dp[1][1] = ... = dp[5][5] = 1
计算长度为2的子串:
- "aa": dp[0][1] = min(dp[0][0], dp[1][1]) = min(1,1) = 1
- "ab": dp[1][2] = min(dp[1][1]+dp[2][2], dp[1][2]+...) = 1+1 = 2
- "bb": dp[2][3] = 1
- "ba": dp[3][4] = 2
- "ac": dp[4][5] = 2
计算长度为3的子串:
- "aab":
dp[0][2] = min(dp[0][1]+dp[2][2], dp[0][0]+dp[1][2])
= min(1+1, 1+2) = 2 - "abb": dp[1][3] = min(dp[1][2]+dp[3][3], dp[1][1]+dp[2][3])
= min(2+1, 1+1) = 2 - "bba": dp[2][4] = min(dp[2][3]+dp[4][4], dp[2][2]+dp[3][4])
= min(1+1, 1+2) = 2 - "bac": dp[3][5] = min(dp[3][4]+dp[5][5], dp[3][3]+dp[4][5])
= min(2+1, 1+2) = 3
继续这个过程,最终得到dp[0][5] = 3
- 算法实现要点:
- 使用双重循环,外层循环枚举子串长度,内层循环枚举起始位置
- 时间复杂度O(n³),空间复杂度O(n²)
这个问题的关键在于理解:当首尾字符相同时,可以在同一次操作中打印这两个字符,从而可能减少打印次数。