LeetCode 664 奇怪的打印机
动态规划
先去重, 再考虑状态转移
对于每个位置字符分别有两种状态, 独立打印或一同打印, 再考虑到打印次数, 一维的\(dp(i)\)不够描述状态
再加一维, 每次连续打印时只考虑某2个字符属于同一个打印批次, 列出状态转移方程
\[dp(st, ed) = \begin{cases}
1 + dp(st+1, ed) & \\
dp(st, i-1) + dp(i+1, ed) & \text{s[st]=s[i]}
\end{cases} \\
\]
为了表示方便, 这里\(\left\{s[i] |i \in [st, ed] \right\}\)
最后使用递归方便地套上状态转移方程
C艹
class Solution {
public:
int dpAry[105][105];
int strangePrinter(string s) {
memset(dpAry, 0, sizeof dpAry);
auto ed = unique(s.begin(), s.end());
while (s.end() != ed) s.pop_back();
if (s.length() <= 1) return (int)s.length();
return dp(s, 0, s.length()-1);
}
// [st, ed]
int dp(string &s, unsigned long st, unsigned long ed) {
if (ed < st) return 0;
if (dpAry[st][ed] > 0) return dpAry[st][ed];
int len = 1 + dp(s, st+1, ed);
for (auto i = st+1; i <= ed; ++i) {
if (s[i] != s[st]) continue;
len = min(len, dp(s, st, i-1) + dp(s, i+1, ed));
}
dpAry[st][ed] = len;
return len;
}
};