题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5030
Rabbit's String
Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 190 Accepted Submission(s): 65
Problem Description
Long long ago, there lived a lot of rabbits in the forest. One day, the king of the rabbit kingdom got a mysterious string and he wanted to study this string.
At first, he would divide this string into no more than k substrings. Then for each substring S, he looked at all substrings of S, and selected the one which has the largest dictionary order. Among those substrings selected in the second round, the king then choose one which has the largest dictionary order, and name it as a "magic string".
Now he wanted to figure out how to divide the string so that the dictionary order of that "magic string" is as small as possible.
Input
There are at most 36 test cases.
For each test case, the first line contains a integer k indicating the maximum number of substrings the king could divide, and the second line is the original mysterious string which consisted of only lower letters.
The length of the mysterious string is between 1 and 10
5 and k is between 1 and the length of the mysterious string, inclusive.
The input ends by k = 0.
Output
For each test case, output the magic string.
Sample Input
Sample Output
b ba
Hint
For the first test case, the king may divide the string into "b", "b" and "aa". For the second test case, the king may divide the string into "aba" and "ba".
Source
2014 ACM/ICPC Asia Regional Guangzhou Online
题目大意:给一个字符串s,你最多可以将s分成k个字符串,对于这些子串,s1,s2,s2...sn(n<=k),要使这些所有子串的子串最大值最小,输出这个答案。
大致思路:先orz下雷哥,本来没多少思路,看了雷哥博客才懂。使最大值最小可以想到二分答案去判断,我们二分这个答案串是字符串的第x小子串,为字符串A,根据后缀数组可以很容易确定A的位置,就假设就出现在sa[t],那么对于从排名t到n的后缀我们都可能要进行分割。在排名[t,n]的后缀中截取子串s[Li,Ri],且该子串和A有大于0的公共前缀,对于t当然就是A本身。如果公共前缀为0,就说明这个后缀的第一个子串大于A的第一个字符,这种情况肯定不成立。这些子串具有的性质的是:再加上它的后面的一个字符都比答案串大,所以都应该切割一下。这里要注意Ri应该小于n,等于n就是最后一个字符了,最多和答案串相等。
这样就转换成了这样一个问题,有一些区间[Li,Ri],只要区间里的一个点被覆盖这个区间就被覆盖了(这个点就是切割点),求最少的点覆盖这些区间。如[4,10],[5,20],[6,22],[30,40]只需切割10和40就行,又如[1,9],[6,7],[7,8][8,10],[10,12],只需切割7,10即可。
贪心即可。可以知道区间范围是[0,n-1],我们从左到右依次找最小的右边界,这个点肯定需要切割。。。
代码:
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include