• leetcode 1531 压缩字符串


    题意

    行程长度编码 是一种常用的字符串压缩方法,它将连续的相同字符(重复 2 次或更多次)替换为字符和表示字符计数的数字(行程长度)。例如,用此方法压缩字符串 "aabccc" ,将 "aa" 替换为 "a2" ,"ccc" 替换为` "c3" 。因此压缩后的字符串变为 "a2bc3" 。

    注意,本问题中,压缩时没有在单个字符后附加计数 '1' 。

    给你一个字符串 s 和一个整数 k 。你需要从字符串 s 中删除最多 k 个字符,以使 s 的行程长度编码长度最小。

    请你返回删除最多 k 个字符后,s 行程长度编码的最小长度 。

    思路

    dp[i][j][last][concat]表示前i个字符,删除j个,最后一个为last,当前到最后一个字符最长相同字符个数为concat时编码的最小长度。
    每一个字符有删除和连接两种操作,删除时状态转移为dp[i-1][j-1][last][concat]
    连接时如果当前字符和last相等,需要考虑concat的个数,因为当concat从1变为2,从9变为10,从99变为100时,数目是增加1的
    若连接时字符不同,重新跟新last和concat的数值

    int dp[105][105][27][15];
        const int maxn=0x3f3f3f3f;
        string s;
        int dfs(int idx,int k,int last,int concat)
        {
            if(k<0)  return 0x3f3f3f3f;
            if(idx==s.size())  return 0;
            int&val =dp[idx][k][last][concat];
            if(val!=-1) return val;
            int ans=maxn;
            //删除
            ans=min(ans,dfs(idx+1,k-1,last,concat));
            //concat
            if(last==s[idx]-'a')
            {
                int fac=(concat == 1 || concat == 9|| concat==99) ? 1 : 0;
                ans=min(ans,dfs(idx+1,k,last,min(10, concat + 1))+fac);
            }
            else
                ans=min(ans,dfs(idx+1,k,s[idx]-'a',1)+1);
            return val=ans;
        }
        int getLengthOfOptimalCompression(string s, int k) {
            this->s=s;
            //特判下s=100,k=0,全部为同一字符的情形是否出现
            memset(dp,-1,sizeof(dp));
            return dfs(0,k,26,0);
        }
    

    思路2,dp[i][j]表示前i个字符删除j个,那么对第i个字符有删除和不删除两种;对于不删除,我们考虑在不超过k的条件下可以走多远

      int dp[105][105];
        int getLengthOfOptimalCompression(string s, int k) {
            int n = s.size();
            memset(dp, 0x3f, sizeof(dp));
            dp[0][0] = 0;
            for(int i = 1; i <= n; i++) {
                for(int j = 0; j <= k; j++) {
                    dp[i][j + 1] = min(dp[i][j + 1], dp[i - 1][j]);
                    int cnt = 0, del = 0;
                    for(int l = i; l <= n; l++) {
                        cnt += s[l - 1] == s[i - 1];
                        del += s[l - 1] != s[i - 1];
                        if(j + del <= k) dp[l][j + del] = min(dp[l][j + del], dp[i - 1][j] + 1 + (cnt >= 100 ? 3 : cnt >= 10 ? 2 : cnt >= 2 ? 1: 0));
                    }
                }
            }
            return dp[n][k];
        }
    
  • 相关阅读:
    DIV+CSS列表式布局(同意图片的应用)
    Cache 应用程序数据缓存
    mysql 中 isnull 和 ifnull 判断字段是否为null
    Logo图标快速生成软件(Sothink Logo Maker) v3.5 官方设计师版
    Linqer工具
    mvc学习视频
    MvcPager注意版本与mvc的版本
    此版本的 SQL Server 不支持用户实例登录标志。该连接将关闭“的解决
    ASP.NET 免费开源控件
    逆向知识之CS1.6辅助/外挂专题.1.实现CS1.6主武器副武器无限子弹
  • 原文地址:https://www.cnblogs.com/flightless/p/13387503.html
Copyright © 2020-2023  润新知