664. 奇怪的打印机

思路:
为什么动规有些规律就是发现不了呢,叹气。
一开始想的方向就错了,想的是用出现次数最多的先打满,然后再用次数第二多的覆盖,在第三的覆盖,但发现如果字母出现的位置不连续就很难做,需要存储一个字母出现的所谓位置,这样就很难实现了。
然后看了题解,发现还是找规律。
首先我们可以发现 ,aba,aba打的次数最少为2次,ab打印次数为2。bbab,打印次数为2次,bba打印次数为两次。我们可以推测如果s[i]=s[j]我们能得到一个结论,就是从s[i]打印到s[j]的打印次数等于s[i]打印到s[j-1]的次数。
如果s[i]!=s[j],我们可以想象再[i,j]这个区间里,一定会有最少的打印次数从i打到j,所以我们遍历[i,j]的所有情况找到最小的即可。例如,abab,有多少种情况?a,bab(1+2次);ab,ab(2+2);aba,b(2+1),所以最小的可能是3次。
根据上面两种情况我们就可以写出程序了。

代码

class Solution {
public:
    int strangePrinter(string s) {
        int n = s.length();
        vector<vector<int> >dp(n,vector<int>(n,INT_MAX));
        for(int i=n-1;i>=0;--i){
            dp[i][i]=1; //[i,i]区间只有一种打印方式,就是他本身
            for(int j=i+1;j<n;++j){
                if(s[i]==s[j]){ //i位置元素等于j位置元素
                    dp[i][j] = dp[i][j-1];
                }
                else{
                    for(int k=i;k<j;++k){
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); //从[i,j]区间找出打印次数最少的情况
                    }
                }
            }
        }
        return dp[0][n-1];
    }
};
posted @ 2021-05-24 13:53  Mrsdwang  阅读(49)  评论(0编辑  收藏  举报