Description
有一个数列,它是由自然数组成的,并且严格单调上升。最小的数不小于S,最大的不超过T。现在知道这个数列有一个性质:后一个数相对于前一个数的增长率总是百分比下的整数(如5相对于4的增长率是25%,25为整数;而9对7就不行了)。现在问:这个数列最长可以有多长?满足最长要求的数列有多少个?
Input Format
输入仅有一行,包含S和T两个数( 0<S<T≤200000)。
30%的数据,0<S<T≤100;
100%的数据,0<S<T≤200000。
Output Format
输出有2行。第一行包含一个数表示长度,第二行包含一个数表示个数。
Sample Input
2 10 |
Sample Output
5 |
样例解释
2 4 5 6 9以及2 4 5 8 10
解题思路
DP动态规划求解
如何将从S到T的问题转变成从S到T-1的问题呢?
首先求出从S到T-1的最长序列有几个,他的末端分别是谁,然后把T和末端数字进行比较,看是否可以延续这个最长序列,从而决定是否要增加序列的长度。
DP设定以下几个状态 * d[i] 表示以i为结尾的最长序列的长度 * times[i] 以i为结尾的最长序列的个数 * cnt[x] 长度为x的序列的个数
算法:
从S到T遍历起点i。
逆向思考:假设增长的百分率为j%,也就是题目中的25。则确定序列中的下个数字tmp 与i的关系为
\((tmp - i)/i = j/100\) 整理得 \(tmp = i + i*j/100\) 注意这里的 \(tmp<=T\)。
得到上述关系后,DP的状态转移为:
首先,我们的tmp是在以i为结尾的序列后加入的,长度为d[i]+1, 因此以tmp的结尾的序列长度和次数要更新;
如果d[tmp] 和 d[i]+1相等,那么在此之前以tmp结尾的序列最长长度和之前的序列长度一致。也就是说 \(times[tmp] += times[i]\)。
如果d[tmp] < d[i]+1, 说明新的序列比原来的还要长,所以\(d[tmp] = d[i]+1, times[tmp] = times[i]\)。
更新总的最大长度\(ans = max(ans,d[tmp])\);
最后输出ans和cnt[ans]
|