题意:略。
思路:进行两次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(" "); 63 } 64 return 0; 65 }