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\n",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 }

posted on 2019-10-31 16:16  大桃桃  阅读(219)  评论(0编辑  收藏  举报

导航