POJ 1239 Increasing Sequences(经典的两次dp)

http://poj.org/problem?id=1239

题意:
给出一串序列,现在要添加逗号作为分隔符,使得序列是递增序列,然后让最后一个数尽量小,第一个数尽量大。

 

思路:
先从头到尾进行一次dp,d【i】表示分析到第i位时往前的最小长度,这样一来,d【n】就表示最后一位的最小长度。

在满足了最后一位尽量小的情况下,我们再从尾到头进行一次dp,此时d【i】表示分析到第i位时往后的最大长度。思路和第一次dp是差不多的。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 80 + 5;
17 
18 int d[maxn];
19 char s[maxn];
20 
21 bool judge(int i, int j, int x, int y)  //判断【i,j】是否大于【x,y】
22 {
23     int len1=j-i+1;
24     int len2=y-x+1;
25 
26     while(s[i]=='0')  {i++;len1--;}
27     while(s[x]=='0')  {x++;len2--;}
28 
29     if(len1>len2)  return true;
30     else if(len1<len2)  return false;
31     else
32     {
33         for(int k=0; k<len1;k++)
34         {
35             if(s[k+i]>s[x+k])  return true;
36             else if(s[k+i]<s[x+k])  return false;
37         }
38     }
39     return false;
40 }
41 
42 int main()
43 {
44     //freopen("in.txt","r",stdin);
45     while(~scanf("%s",s+1))
46     {
47         int n=strlen(s+1);
48         if(n==1 && s[1]=='0')  break;
49         
50         //从头到尾找最小长度
51         for(int i=1;i<=n;i++)
52         {
53             d[i]=i;
54             for(int j=i-1;j>=1;j--)
55             {
56                 if(judge(j+1,i,j-d[j]+1,j))
57                 {
58                     d[i]=i-j;
59                     break;
60                 }
61             }
62         }
63         
64         //从尾到头找最大长度
65         int t=n-d[n]+1;   //[t,n]已经是决定了的,不能改变
66         d[t]=d[n];
67         for(int i=n-d[n];i>=1;i--)
68         {
69             if(s[i]=='0')
70             {
71                 d[i]=d[i+1]+1;
72                 continue;
73             }
74             for(int j=t;j>i;j--)
75             {
76                 if(judge(j,j+d[j]-1,i,j-1))
77                 {
78                     d[i]=j-i;
79                     break;
80                 }
81             }
82         }
83 
84         int tmp=d[1]+1;
85         for(int i=1;i<=n;i++)
86         {
87             if(tmp==i)
88             {
89                 printf(",");
90                 tmp=d[i]+i;
91             }
92             printf("%c",s[i]);
93         }
94         printf("\n");
95     }
96     return 0;
97 }

 

posted @ 2017-07-29 14:37  Kayden_Cheung  阅读(449)  评论(0编辑  收藏  举报
//目录