都说经典dp,但是居然没有反应过来。dp方式和最长递增子串这种问题类似:从首位开始长度为n的子串,假设可以获得的最小的最后位数字为f(n)。那么f(n)可以通过比n小的子串得到。具体就不说了
然后这样可以知道最后能够得到最小的末尾数是多少。但是题目对于多种解情况还有要求,如果有多个解,那么要求前面的数越大越好。恩。。。比较难以想象,这里还是可以用dp解决。就是反过来而已,就是从最后一位往前推,其他差不多。
然后是两个头痛的问题:
1. 字符串和数字:输入有80长,没人会傻乎乎的转成数字的,但是我还是犯了错,在处理分割之后数字的时候转成了int,然后就溢出了。Runtime error。其实,中间比较数字大小需要用字符串来比较
2. 0的问题。0也很头痛,因为0可以作为前缀,这样导致的一个问题就是如果存在多个解,那么某个数字前面的0应该怎么分配很成问题。第一次dp的时候不需要考虑0,只需要得到最小的末尾数。但是反推的时候就很头痛,在循环里面倒是问题不大,每个位置都会算一遍。但是初始状态不好确定。搞了半天。
#include<iostream>
#include<string>
#include<string.h>
#include<stdlib.h>
using namespace std;
int cmp(string s1, string s2)
{
if(s1.compare("") == 0)
{
return -1;
}
int index1, index2;
int len1 = s1.length();
int len2 = s2.length();
for(index1=0;index1<len1;index1++)
{
if(s1[index1] != '0')
break;
}
for(index2=0;index2<len2;index2++)
{
if(s2[index2] != '0')
break;
}
if((len1-index1) != (len2-index2))
{
return (len1-index1)-(len2-index2);
}
if(s1.substr(index1, len1-index1+1).compare(s2.substr(index2, len2-index2)) == 0)
{
return 0;
}
while(index1 != len1)
{
if(s1[index1] != s2[index2])
{
return s1[index1] - s2[index2];
}
index1++;
index2++;
}
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "rt", stdin);
freopen("output.txt", "wt+", stdout);
#endif
/*string s1, s2;
while(cin >> s1)
{
cin >> s2;
cout << s1 << endl << s2 <<endl << cmp(s1, s2) << endl;
}*/
int minEnd[91];
string str;
cin >> str;
while(str.compare("0") != 0)
{
//memset(minEnd, 0, sizeof(minEnd));
minEnd[0] = 0;
int len = str.length();
for(int i=1;i<=len;i++)
{
for(int j=i-1;j>=0;j--)
{
if(cmp(str.substr(minEnd[j], j-minEnd[j]), str.substr(j, i-j)) < 0)
{
minEnd[i] = j;
break;
}
}
}
int maxHead[91];
int start = -1;
for(int i=minEnd[len]-1;i>=0;i--)
{
if(str[i] != '0')
{
start = i;
break;
}
else
{
maxHead[i] = len;
}
}
maxHead[minEnd[len]] = len;
for(int j=start;j>=0;j--)
{
for(int i=minEnd[len];i>=j+1;i--)
{
if(cmp(str.substr(j, i-j), str.substr(i, maxHead[i]-i)) < 0)
{
maxHead[j] = i;
break;
}
}
}
start = 0;
while(true)
{
cout << str.substr(start, maxHead[start]-start);
if(maxHead[start] == len)
{
break;
}
else
{
cout << ",";
start = maxHead[start];
}
}
cout << endl;
cin >> str;
}
}