递增序列

递增序列

时间限制: 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;
}
时间: 2024-10-03 23:15:31

递增序列的相关文章

得到最长连续递增序列

今天作死,看到别人发出来的笔试题就开干了,这tmd还理解错题目了,连续递增序列理解成上一个=下一个-1了. 这是我的成果,撸了4个多小时的: public class Test12 { public static void main(String[] args){ /** * 需求:找出最长的连续递增序列 * 步骤: * 1.找出所有连续序列可能结果,删除不是连续递增序列的,加入集合 * 2.集合排序,取第一个 * * 方式2: * 0.默认len为数组长度 * 1.找出数组中长度为len的序列

zoj1986 Bridging Signals (dp,最长递增序列,LIS)

A - Bridging Signals Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practice ZOJ 1986 Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once more the routing designer

uva103(最长递增序列,dag上的最长路)

题目的意思是给定k个盒子,每个盒子的维度有n dimension 问最多有多少个盒子能够依次嵌套 但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明 盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中 这个题目能够转化为最长递增子序列. 首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排

矩形网格中寻找最长递增序列

在矩形网格中寻找最长的递增序列 比如如下网格 97,47,56,36 35,57,41,13 89,36,98,75 25,45,26,17 结果要求输出 17, 26, 36, 41, 47, 56, 57, 97 基本想法就是对图中的每一个点都当作起始点试一编 将序列最长的保存起来 最后输出 代码如下 使用java编写 import java.util.ArrayList; public class 最长递增序列 { static int[][] rect={ {97,47,56,36},

POJ 2533 Longest Ordered Subsequence 最长递增序列

Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, seque

[数据库] Navicat for Oracle设置唯一性和递增序列实验

这篇文章主要讲述Navicat for Oracle设置唯一性约束和设置某字段为递增序列.文章主要以图文为主,虽然都是非常简单基础的文章,但还是希望对你有所帮助. 推荐前一篇文章:[数据库] Navicat for Oracle基本用法图文介绍 一. 设置唯一性 参考文章:Oracle之唯一性约束(UNIQUE Constraint)用法详解 唯一性约束英文是Unique Constraint,它是指表中一个字段或者多个字段联合起来能够唯一标识一条记录的约束.联合字段中,可以包含空值. 那唯一性

UVALive 6609(Minimal Subarray Length)维护递增序列|RMQ

题意:给一个整数序列(可能有负数),求最短的连续序列使得序列之和大于等于整数x: 解法:第一种是On的复杂度: 我们要的是sum[j]-sum[i]>=x,如果有两个决策j < j',而且sum[j] >= sum[j'],那么j就是没用的.即维护一个sum[j]递增序列.然后每次可以二分查找,但是这里有个特点就是要得到最近的,可以同时维护一个left指针,left指针用于跟进更行答案的左边界,因为维护的单调栈不会再右移到left左边去了(因为如果left右边还可以更新的答案肯定没有当前

ACM: Racing Gems - 最长递增序列

Racing Gems   You are playing a racing game.  Your character starts at the x axis (y = 0) and proceeds up the      race track, which has a boundary at the line x = 0 and another at x = w.  You  may start the race       at any horizontal position you

最长递增子序列(输出最长递增序列 及其长度)

最长递增子序列的解法有很多种,常用的有最长公共子序列法.动态规划.记录所有递增序列长度最大值的方法. 最长公共子序列法:如例子中的数组A{5,6, 7, 1, 2, 8},则我们排序该数组得到数组A‘{1, 2, 5, 6, 7, 8},然后找出数组A和A’的最长公共子序列即可.显然这里最长公共子序列为{5, 6, 7, 8},也就是原数组A最长递增子序列. 在http://blog.csdn.net/yysdsyl/article/details/4226630中有详细解释. 动态规划:参见h

九度oj 题目1262:Sequence Construction puzzles(I)_构造全递增序列

题目描述: 给定一个整数序列,请问如何去掉最少的元素使得原序列变成一个全递增的序列. 输入: 输入的第一行包括一个整数N(1<=N<=10000). 接下来的一行是N个满足题目描述条件的整数. 输出: 可能有多组测试数据,对于每组数据, 输出去掉最少的元素后的全递增序列. 样例输入: 8 186 186 150 200 160 130 197 220 样例输出: 150 160 197 220 提示: 如果有多个结果序列满足条件,输出相对位置靠前的那个序列. 代码如下: 1 #include