题意:略。
思路:进行两次dp。
第一次dp从前向后,用dp[x]表示从第x位向前dp[x]位可构成一个数字,且与前面的数组符合题意要求。最后求的dp[n]即为最后一个数字的长度。
而题目还有要求,所有解中输出前面数字最大的一个。因此还需要进行一次dp,从后向前。
具体看代码吧,当初也是看别人代码才看懂的。
1
#include<stdio.h>
2
#include<
string
.h>
3
char
num[
85
];
4
int
dp[
85
], n;
5
bool
judge(
int
st1,
int
len1,
int
st2,
int
len2)
6
{
7
while
(num[st1] ==
'
0
'
&& len1) st1++, len1--
;
8
while
(num[st2] ==
'
0
'
&& len2) st2++, len2--
;
9
if
(len1 < len2)
return
1
;
10
else
if
(len1 > len2)
return
0
;
11
else
12
{
13
for
(
int
i =
0
; i < len1; i++
)
14
{
15
if
(num[st1+i] < num[st2+i])
return
1
;
16
if
(num[st1+i] > num[st2+i])
return
0
;
17
}
18
}
19
return
0
;
20
}
21
void
print(
int
pos)
22
{
23
if
(pos > n)
return
;
24
if
(pos !=
1
) printf(
"
,
"
);
25
for
(
int
i = pos; i < pos + dp[pos]; i++
)
26
printf(
"
%c
"
, num[i]);
27
print(pos +
dp[pos]);
28
}
29
int
main()
30
{
31
while
(~scanf(
"
%s
"
, num +
1
) && strcmp(num +
1
,
"
0
"
))
32
{
33
n = strlen(num +
1
);
34
dp[
1
] =
1
;
35
for
(
int
i =
2
; i <= n; i++
)
36
{
37
dp[i] =
i;
38
for
(
int
j = i -
1
; j >=
1
; j--
)
39
if
(judge(j - dp[j] +
1
, dp[j], j +
1
, i -
j))
40
{
41
dp[i] = i -
j;
42
break
;
43
}
44
}
45
int
pos = n - dp[n] +
1
;
46
dp[pos] =
dp[n];
47
for
(
int
i = pos -
1
; i >=
1
; i--
)
48
{
49
if
(num[i] ==
'
0
'
)
50
{
51
dp[i] = dp[i+
1
] +
1
;
52
continue
;
53
}
54
for
(
int
j = pos; j > i; j--
)
55
if
(judge(i, j -
i, j, dp[j]))
56
{
57
dp[i] = j -
i;
58
break
;
59
}
60
}
61
print(
1
);
62
printf(
"
\n
"
);
63
}
64
return
0
;
65
}

