zoukankan      html  css  js  c++  java
  • 664. Strange Printer

    class Solution {
    public:
        int dp[100][100];
        int dfs(const string &s, int i,int j)
        {
            if(i>j)return 0;
            if(dp[i][j])return dp[i][j];
            dp[i][j]=dfs(s,i,j-1)+1;
            for(int k=i;k<j;++k)
            {
                if(s[k]==s[j])dp[i][j]=min(dp[i][j],dfs(s,i,k)+dfs(s,k+1,j-1));
            }
            return dp[i][j];
        }
        int strangePrinter(string s) {
            if(s.empty())return 0;
            return dfs(s,0,s.size()-1);
        }
    };
    

      

    1

    我刚开始的思路是, 相邻的字符如果相同就去重, 然后循环 0 到 n, 首尾相等的话就不用额外打印; 

    例如  aaabbbaaa  先去重变为  aba , 循环第一个, a 打印一次,  第二个b 打印一次,  第三个a 发现和第一个相同, 不用打印;  然后提交时发现有些case没有通过测试;

    后来总结了下, 我漏掉了回文的情况,  我发现这题用回文思路也能做, 因为打印回文的话, 回文总长度是n, 是不是最多n/2+1次就可以了,  例如  abcba=3次   abccba=3次  aaaa=1次, 不过我也懒得去实现回文算法来做比较了.

    2

    上面贴的答案是discussion讨论区的答案, 很标准的dfs+dp 解法,  代码很清晰, 几乎不需要解释, 

    大致思路就是 每新增一个字符, 尽可能想办法不要额外次数去打印, 那么不打印的办法就是看有没有办法和前面已经打印过得字符"合并",  这里极端的情况就是上面说到的回文啦

    打印字符串第i个位置到第j个位置需要的次数  =  dp[i][j];

    dp[i][j] = min (dp[i][j-1]+1, dp[i][k]+dp[k+1][j-1])   i<k<j;   

    min左边的意思是不能合并, 只能再打印一次,  右边的意思是  找到一个位置k,  符合 i<k<j,  使得  i到k  这部分  +   k+1到j 这部分 之和最小

  • 相关阅读:
    mysql优化思路
    mysql列类型选择
    mysql 多列索引的生效规则
    Myisam索引和Innodb索引的区别
    mysql创建远程用户并授权
    mysql 索引长度和区分度
    php 内存共享shmop源码阅读
    短链接系统的算法原理
    PHP die与exit的区别
    MySQL建立外键(Foreign Key)
  • 原文地址:https://www.cnblogs.com/lychnis/p/9247920.html
Copyright © 2011-2022 走看看