LeetCode: -Dynamic Programming-Strange Printer[664]
来源:互联网 发布:say it again frances 编辑:程序博客网 时间:2024/06/05 11:16
题目
一个打印机,每一轮能打印一个同一个字符的序列,能在下一轮在任何位置开始任何位置结束打印一个其他的字符。后打印的将覆盖先打印的。
给定一个字符串,求最小的打印轮次。
示例:
Input: "aaabbb"Output: 2Explanation: 先打印 "aaa" 再打印 "bbb".
Input: "aba"Output: 2Explanation: 先打印 "aaa" 再从第二个位置打印 "b" 会将已经存在的 'a' 覆盖.
分析
二维DP问题
1、dp[i][j] 表示范围 [i, j) 内的最小轮次. 运用memoization 和 DFS来避免计算不必要的子问题.
2、贪婪的选择: 对于任意一个序列, 首先打印首字符. 比如 s[0] = ‘a’. 如果存在最优的解决方案, 不是将s[0] 打印的范围是 [0, k)作为第一步, 我们可以将这一个移到第一步,并且保证其他步为原来的顺序. 如果有字符在s[0]的原来的顺序之前打印了,且范围在k之前,我们将该字符的打印开始位置移动到k开始.
根据不同的方法将 s[0]= ‘a’ 和其他部分的 ‘a’结合起来,我们有:
dp[i][j] = min(dp[i][j], dp[start][k]+dp[k][end]), 对于每个 k 有 s[k] == s[i],
这里的start和end分别是开始的一个字符和最后的一个字符,不是s[i].
例如
给定一个序列 "aaa bcd aaa def aaa ccd aaa", 我们有三种选择来结合 s[0] = 'a' 和其他部分的 'a'.bcd + aaa aaa def aaa ccd aaa,与之一样的是 bcd + aaa def aaa ccdbcd aaa def + aaa ccdbcd aaa def aaa ccd + aaa
代码
class Solution {public: int strangePrinter(string s) { int n = s.size(); vector<vector<int>> dp(n+1, vector<int>(n+1, 0)); return helper(s, dp, 0, n); }private: int helper(string& str, vector<vector<int>>& dp, int s, int e) { if (s >= e) return 0; if (dp[s][e]) return dp[s][e]; // 处理 str[s] 的首尾字符 // 注意范围是左闭右开 [s,e) [l,r) int l = s, r = e; while (l < e && str[l] == str[s]) l++; while (r > l && str[r-1] == str[s]) r--; dp[s][e] = 1+helper(str, dp, l, r); for (int i = l; i < r; i++) { if (str[i] == str[s]) { dp[s][e] = min(dp[s][e], helper(str,dp,l,i)+helper(str,dp,i,r)); while (i < e && str[i] == str[s]) i++; } } return dp[s][e]; }};
阅读全文
0 0
- LeetCode: -Dynamic Programming-Strange Printer[664]
- Strange Printer (leetcode)
- [leetcode]664. Strange Printer
- [Leetcode]664. Strange Printer
- Leetcode: 664. Strange Printer
- 664Strange Printer
- Strange Printer
- leetcode dynamic programming
- LeetCode:Dynamic Programming
- LeetCode Summary Dynamic Programming
- LeetCode--Dynamic Programming
- [Leetcode]Dynamic Programming-note
- [Leetcode]Dynamic Programming
- [Leetcode]Dynamic Programming
- [Leetcode]Dynamic Programming
- [Leetcode]Dynamic Programming
- 【LeetCode】664.Strange Printer(hard)解题报告
- leetcode 664. Strange Printer 奇怪的打印机 + 动态规划DP
- 做到这一点,你也可以成为优秀的程序员
- Maven_Eclipse_Eclipse下使用maven 打包项目
- MySQL教程
- 使用NAT的方式配置Centos虚拟机的网络
- Python|计蒜客——两数之和
- LeetCode: -Dynamic Programming-Strange Printer[664]
- 程序设计语言
- 用GridView加载网络图片(上)
- 看了一定会收藏的海量数据实时在线分析Quick BI
- STL源码分析
- Java设计模式学习笔记 2
- CodeForces
- 操作系统Unix、Windows、Mac OS、Linux的故事
- 【PAT】【Advanced Level】1088. Rational Arithmetic (20)