• TZOJ 5963 Increasing Sequences(线性DP)


    描述

    Given a string of digits, insert commas to create a sequence of strictly increasing numbers so as to minimize the magnitude of the last number. For this problem, leading zeros are allowed in front of a number.

    输入

    Input will consist of multiple test cases. Each case will consist of one line, containing a string of digits of maximum length 80. A line consisting of a single 0 terminates input. 

    输出

    For each instance, output the comma separated strictly increasing sequence, with no spaces between commas or numbers. If there are several such sequences, pick the one which has the largest first value;if there's a tie, the largest second number, etc. 

    样例输入

    3456
    3546
    3526
    0001
    100000101
    0

    样例输出

    3,4,5,6
    35,46
    3,5,26
    0001
    100,000101

    题意

    一个数字串,让你分割,使得串严格递增,多解输出第一个数最大的,类推。

    题解

    好题,两次dp,类似于第一次确定一个值,第二次构造答案。

    从前往后一个dp求出最后一个数字串最小时是多少,dp[i]=j表示str[0....i]这个串满足最后一个子串最小时最后一个串的下标起始str[j...i]。

    接着从后往前第二个dp求出保证最后一个数字最小的情况下满足前面的串尽可能大,dp[i]=j表示str[i...len-1]的串是str[i....j]。这里需要注意对0的处理。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 char s[85];
     5 bool check(int l1,int r1,int l2,int r2,int f)
     6 {
     7     char s1[85],s2[85];
     8     int p1=80,p2=80;
     9     for(int i=r1;i>=l1;i--)s1[p1--]=s[i];
    10     for(int i=r2;i>=l2;i--)s2[p2--]=s[i];
    11     int k=abs(p1-p2);
    12     if(p1<=p2)for(int i=0;i<k;i++)s2[p2--]='0';
    13     else for(int i=0;i<k;i++)s1[p1--]='0';
    14     /*printf("%d,%d %d,%d
    ",l1,r1,l2,r2);
    15     for(int i=p1+1;i<=80;i++)printf("%c",s1[i]);
    16     puts("");
    17     for(int i=p2+1;i<=80;i++)printf("%c",s2[i]);
    18     puts("");*/
    19     for(int i=p1+1;i<=80;i++)
    20         if(s1[i]==s2[i])continue;
    21         else if(s1[i]<s2[i])return true;
    22         else return false;
    23     return false;
    24 }
    25 int main()
    26 {
    27     while(scanf("%s",s)!=EOF)
    28     {
    29         if(strcmp(s,"0")==0)break;
    30         int dp[85]={0},dp1[85]={0};
    31         int len=strlen(s);
    32         for(int i=1;i<len;i++)
    33             for(int j=i-1;j>=0;j--)
    34                 if(check(dp[j],j,j+1,i,0))
    35                 {
    36                     dp[i]=j+1;
    37                     break;
    38                 }
    39         int start=dp[len-1];
    40         dp1[start]=len-1;
    41         while(start-1>=0&&s[start-1]=='0')
    42         {
    43             start--;
    44             dp1[start]=len-1;
    45         }
    46         for(int i=start-1;i>=0;i--)
    47             for(int j=i;j<dp[len-1];j++)
    48                 if(check(i,j,j+1,dp1[j+1],1))
    49                     dp1[i]=j;
    50         int p=0;
    51         do
    52         {
    53             int r=dp1[p];
    54             for(int i=p;i<=r;i++)
    55                 putchar(s[i]);
    56             p=r+1;
    57             if(p<len)putchar(',');
    58         }while(p<len);
    59         putchar(10);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    Javascript 时间Date()的一般用法
    vue搭建
    初次见面
    css3边框
    appium移动自动化测试-one demo
    appium移动自动化测试-安装2
    appium移动自动化测试-安装1
    python数据类型
    判断软键盘是不是可见
    android 设置Dialog的宽度
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/11771876.html
Copyright © 2020-2023  润新知