zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    C#与Java的几点区别
    用VB读取记事本的内容,控制计算器的按钮(VB6)
    通过实例说明Java中的多态
    [导入]析构函数(内存泄漏,三法则)
    [导入]const限制符
    [导入]类的一些特殊限制成员
    [导入]基类的复制控制函数
    [导入]容器适配器
    [导入]派生类到基类转换的可访问性
    [导入](复制、默认)构造函数
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/11771876.html
Copyright © 2011-2022 走看看