POJ1239-Increasing Sequences(两次DP)

Given a string of digits, insert commas to create a sequence of strictly increasing numbers so as to minimize the magnitude of the last number. For this problem, leading zeros are allowed in front of a number.
Input
Input will consist of multiple test cases. Each case will consist of one line, containing a string of digits of maximum length 80. A line consisting of a single 0 terminates input.
Output
For each instance, output the comma separated strictly increasing sequence, with no spaces between commas or numbers. If there are several such sequences, pick the one which has the largest first value;if there’s a tie, the largest second number, etc.
Sample Input
3456
3546
3526
0001
100000101
0
Sample Output
3,4,5,6
35,46
3,5,26
0001
100,000101

分析:

题意:
输入一个字符串(全部由0~9的字符组成),要求将这些字符按照一定的股则划分,使得划分组成数是严格递增的!

规则:
(1)从后往前,要求数字尽量的小
(2)从前往后,要求数字尽量的大

例如:3546;满足划分的有多种方式,但要求最后一个数尽量的小,那么在所有划分方式中,最后一个数字取46为最小,剩下的字符按照规则取满足条件的划分中最大的数,则为35.

解析:
这道题有点难啊!我也是看着别人的题解,一行一行代码的推敲才把这道题理解的。

这里我们用一个一维数组dp[i]记录组成该数的字符串的长度。
大佬们都说用两次DP,然后我们就用两次DP呗!

首先保证后一个数尽量大于前一个数,一旦满足条件就去找下一个数。
然后就找到了能满足条件的而且最小的最后一个数,然后我们还需要倒着推使得,前面的数尽量大并且还满足条件。

代码:

#include<cstdio>
#include<iostream>
#define N 105

using namespace std;

int dp[N];
int book[N];

bool judge(int l1,int r1,int l2,int r2)
{
	while(!book[l1]&&l1<=r1)
	{
		l1++;
	}
	while(!book[l2]&&l2<=r2)
	{
		l2++;
	}
	if(l1>r1)
		return false;
	if(l2>r2)
		return true;
	int len1=r1-l1,len2=r2-l2;
	if(len1>len2)
		return true;
	else
	{
		if(len1<len2)
			return false;
		else
		{
			for(int i=0;i<=len1;i++)
			{
				if(book[l1+i]>book[l2+i])
					return true;
				else
				{
					if(book[l1+i]<book[l2+i])
						return false;
				}
			}
		}
	}
	return false;
}

int main()
{
	string str;
	while(cin>>str&&str!="0")
	{
		int len=str.length();
		for(int i=1;i<=len;i++)
		{
			dp[i]=i;
			book[i]=str[i-1]-'0';
		}
		for(int i=2;i<=len;i++)
		{
			for(int j=i-1;j>=1;j--)
			{
				if(judge(j+1,i,j-dp[j]+1,j))
				{
					dp[i]=i-j;
					break;
				}
			}
		}
		int numberLength=len-dp[len]+1;
		dp[numberLength]=dp[len];
		for(int i=numberLength-1;i>=1;i--)
		{
			if(!book[i])
			{
				dp[i]=dp[i+1]+1;
				continue;
			}
			for(int j=numberLength;j>=1;j--) 
			{
                if(judge(j,j+dp[j]-1,i,j-1))
				{
                    dp[i]=j-i;
                    break;
                }
            }
		}
		for(int i=1;i<=dp[1];i++)
		{
			printf("%d",book[i]);
		}
		int num=dp[1]+1;
		while(num<=len)
		{
			printf(",");
			for(int i=num;i<num+dp[num];i++)
			{
				printf("%d",book[i]);
			}
			num+=dp[num];
		}
		printf("\n");
	}
	return 0;
}
发布了64 篇原创文章 · 获赞 17 · 访问量 867

猜你喜欢

转载自blog.csdn.net/weixin_43357583/article/details/105634509