题目链接:http://poj.org/problem?id=1239
题目大意:求使最后一个数最大且前面的数尽量大的加逗号方式,两次dp,先从前到后求得最后一个数,然后反向dp,求出满足条件且当前数最大的方案。需要注意的是最后一段可加0.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 110
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int dp[100];
char str[100];
char s1,s2;
int len;
bool cmp(int st1,int ed1 ,int st2,int ed2)
{
int i,j;
//int tmp;
for(i=st1;str[i]=='0'&&i<ed2;i++){}
st1=i;
for(i=st2;str[i]=='0'&&i<ed2;i++){}
st2=i;
if(ed1-st1<ed2-st2)
return true;
else if(ed1-st1>ed2-st2)
return false;
for(i=0;i+st1<=ed1;i++)
{
if(str[i+st1]<str[i+st2])
return true;
else if(str[i+st1]>str[i+st2])
return false;
}
return false;
}
int main()
{
int i,j;
while(scanf("%s",str)!=EOF)
{
len=strlen(str);
if(str[0]=='0'&&len==1)
break;
dp[0]=0;
for(i=1;i<len;i++)
{
//dp[i]=i;
dp[i]=0;
for(j=i-1;j>=0;j--)
{
if(cmp(dp[j],j,j+1,i))
{
dp[i]=j+1;
// printf("i %d dp %d\n",i,dp[i]);
break;
}
}
}
int last=dp[len-1];
dp[last]=len-1;
for(i=last-1;i>=0;i--)
{
dp[i]=-1;
if(str[i]=='0')
{
dp[i]=dp[i+1];
continue;
}
for(j=last;j>=i+1;j--)
{
if(cmp(i,j-1,j,dp[j]))
{
dp[i]=j-1;
// printf("i %d %d\n",i,dp[i]);
break;
}
}
}
int tmp=dp[0];
i=0;
while(1)
{
while(i<=tmp)
{
printf("%c",str[i]);
i++;
}
if(tmp==len-1)
break;
printf(",");
tmp=dp[tmp+1];
}
puts("");
}
}