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;
    }
};
posted @ 2020-06-10 01:08  Simon_X  阅读(141)  评论(0编辑  收藏  举报