• 递增序列


    递增序列

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    给定一个数字串,请你插入若干个逗号,使得该数字串成为一个严格递增的数列且最后一个数要尽可能小,在这个问题中,前导的零是允许出现在数的前面的。

    输入

    输入数据仅含一行,为一个长度不超过 80 的数字串。

    输出

    输出一个严格递增且最后一数最小的数列,相邻两个数之间用一个逗号隔开,如果有多个数列满足要求,则输出第一个数最大的那个数列,若这样的解还不止一个,则输出第二个数最大的那个数列,以此类推。

    样例输入

    100000101

    样例输出

    100,000101
    题解:
    dp[i]表示i位以前所有分法中能使最后一个数最小的最后一个数的下标,f[i]表示从后往前能使最前面一个数最大的最前面一个数的下标。
    先动归dp[i],保证最后一个数最小,再动归f[i],保证前面的数最大。由此而来即是最优解。
    代码如下:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    using namespace std;
    int n,dp[120],f[120],ans[120],cnt;
    char s[120];
    int cmp(int l,int r,int ll,int rr)
    {
        while(s[l]=='0'&&l+1<=r)l++;
        while(s[ll]=='0'&&ll+1<=rr)ll++;
        int len1=r-l+1,len2=rr-ll+1;
        if(len1>len2)return 1;
        else if(len1<len2)return -1;
        else
        {
            while(l+1<=r&&ll+1<=rr&&s[l]==s[ll])
            {
                l++;
                ll++;
            }
            if(s[l]>s[ll])return 1;
            if(s[l]<s[ll])return -1;
        }
        return 0;
    }
    int main()
    {
        int i,j;
        scanf("%s",s);
        n=strlen(s);
        dp[0]=0;
        for(i=1; i<n; i++)
        {
            for(j=i-1; j>=0; j--)
            {
                if(cmp(dp[j],j,j+1,i)<0)
                {
                    dp[i]=j+1;
                    break;
                }
            }
        }
        f[dp[n-1]]=n-1;
        int k=dp[n-1]-1;
        while(s[k]=='0')
        {
            f[k]=n-1;
            k--;
        }
        for(i=k; i>=0; i--)
        {
            for(j=dp[n-1]; j>=i+1; j--)
            {
                if(cmp(i,j-1,j,f[j])<0)
                {
                    f[i]=j-1;
                    break;
                }
            }
        }
        i=0;
        while(1)
        {
            int l=i;
            i=f[i];
            for(j=l;j<=i;j++)
            cout<<s[j];
            i++;
            if(i==n)break;
            cout<<',';
            
        }
        return 0;
    }
  • 相关阅读:
    Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务
    JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数
    java.net.UnknownHostException: lc001 未知的网络服务
    Maven 多模块引用版本的问题 java.lang.NoSuchMethodError
    Maven项目运行Junit测试用例 出现ClassNotFound
    CAS5.X 集群配置 初版
    调试CAS源码步骤
    openhtmltopdf 支持自定义字体、粗体
    Java HTML to PDF 支持SVG
    .Net 框架
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/7000524.html
Copyright © 2020-2023  润新知