DAY2
一道算法题的相关联想
原题:
定义分数集合\(S_n=\){\(\frac{p}{q} :(p,q)=1,p<q≤n,p,q∈N^+\)},
输入n,k,要求输出\(S_n\)中第k大的元素
例:\(S_3=\){\(\frac{1}{3}, \frac{1}{2}, \frac{2}{3}\)}
做法
显然知道的是,\(S_n\)中最大的元素一定是\(\frac{n-1}{n}\)
第二大的元素一定是\(\frac{n-2}{n-1}\),这个并不是一个平凡或者显然的结论,不过如果略微思考一下,是可以验证其的正确性的:设\(\frac{n-2}{n-1}<\frac{p}{q} <\frac{n-1}{n}\) ,q显然不会是n或是n-1,于是\(\frac{p}{q}\)至多为\(\frac{n-3}{n-2}\),就产生矛盾了
于是在这样的想法上,考虑从最大的元素逐步推出第二大···直到第k大···
(编不下去了)在没有一定的数学基础情况下,只能通过观察法找规律-> 发现对于连续的三项\(\frac{x_1}{y_1}<\frac{x_2}{y_2}<\frac{x_3}{y_3}\),一定有\(\frac{x_2}{y_2} =\frac{x_1+x_3}{y_1+y_3}\)
于是如果不断指标出前两项的\(\frac{x_3}{y_3},\frac{x_2}{y_2}\),就能在一定程度上得到下一项,问题似乎得到了解决,复杂度为O(k)
但是关于\(x_1\)的选取并不是简单的\(x_2-x_3\),因为\(x_1+x_3\)和\(y_1+y_3\)会有公因子,于是得到\(x_1 = kx_2-x_3\),于是问题是只需要找到这个k即可,一个明显的限制是\(x_3<kx_2≤x_3+n\),所以k的取值也并不是唯一的,这时候问题来了:应该取哪个k,大概估计一下,\(\frac{kx_2-x_3}{ky_2-y_3}\)是关于k单增的(\(\frac{x_2}{y_2}>\frac{kx_2-x_3}{ky_2-y_3}\),分子分母同加会增大),所以k理所应当的取最大的那个,\(k=(x_3+n)\)/\(x_2\)(/代表整除)
于是现在在一个默认的规律下得到了一个速度相当快的算法,写起来也十分简洁
代码
#include<cstdio>
using namespace std;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int x0=n-1;
int y0=n;
int x1=n-2;
int y1=n-1;
int x;
int y;
while(k-1)
{
int r = (n+y0)/y1;
y = r*y1 - y0;
x = r*x1 - x0;
y0 = y1;
x0 = x1;
y1 = y;
x1 = x;
--k;
}
printf("%d/%d",x0,y0);
return 0;
}
数学原理
上面的解法解释的问题是很大的,尽管通过规律以及想当然的算法就是最终的正确算法,不过未经证明的东西最好还是不要去使用为妙,算法最重要的是原理的正确性
对于这一道题目,看到\(S_n\)的定义之后,已经可以完全锁定,\(S_n\)正是著名的法雷数列
法雷数列的定义与题目中的定义一致,具有许多优秀的性质与数论的多个部分都有交集(但都不深)下面逐步挖掘法雷数列的性质并给出证明
1.n阶法雷数列会新增\(\varphi(n)\)项相较于n-1阶法雷数列(\(\varphi(n)\)是欧拉函数,代表了与小于n,与n互素的数的个数。)
这个结论是显然的,只有与n互素的数才会以分子的形式进入第n阶。
2.法雷数列始终有奇数项。
这个也是相对显然的,因为\(\varphi(n)\)只有在n=2的时候是奇数。
3.对于法雷数列中任意相邻的两项\(\frac{p}{q}<\frac{m}{n}\),一定有mq - np = 1;
这个是法雷数列相当重要的性质,考虑用归纳法证明,对n阶法雷数列进行归纳,前面的n容易验证
考虑对已经对n阶成立,考虑证明第n+1阶法雷数列,因为只需要考虑n+1阶新插入的数对两侧的影响,于是对于任何\(\frac{p_1}{q_1}<\frac{p_2}{q_2}\)连续出现在n阶中,其中插入了\(\frac{x}{y}\) (y=n+1),
分别设 \(xq_1-yp_1=t_1\)\(~~~~~~~~~~~~~~~~~\)\(yp_2-xq_2=t_2\)
所以有 \(\frac{x}{y}-\frac{p_1}{q_1} = \frac{t_1}{yq_1}<\frac{1}{q_1q_2}\)···(1)\(~~~~~~~\)\(\frac{p_2}{q_2}-\frac{x}{y} = \frac{t_2}{yq_2}<\frac{1}{q_1q_2}\)···(2)(第二个不等号是因为,\(\frac{p_2}{q_2}-\frac{p_1}{q_1}=\frac{1}{q_1q_2}\))
考虑\(\frac{p_1+p_2}{q_1+q_2}\),因为\(p_2q_1-q_2p_1=1\),所以\((p_2+p_1)q_1-(q_2+q_1)p_1=1\),所以\(\frac{p_1+p_2}{q_1+q_2}\)是一个最简分数,因为\(\frac{p_1+p_2}{q_1+q_2}\)没有介于\(\frac{p_1}{q_1}<\frac{p_2}{q_2}\)之间(不在第n阶法雷数列内),所以一定有,\(q_1+q_2≥y=n+1\)结合(1)+(2):\(y = t_1q_2+t_2q_1\),所以一定有\(t_1=t_2=1\)
对于0,1两边界的插入情况,结论是显然的。
于是这个性质也证明,同时也得到“新数”分子分母恰好等于旁边“老数”分子分母和。(老数旁边是新数就不成立了,例如\(S_3\)中的\(\frac{1}{2}\)项)
4.连续三项\(\frac{p_1}{q_1}<\frac{p_2}{q_2}<\frac{p_3}{q_3}\),有\(\frac{p_2}{q_2}=\frac{p_1+p_3}{q_1+q_3}\)
这个结论利用3的公式将得到两个等于1的式子,相减即可得到证明
以上结论已经覆盖到了法雷数列的大部分内容与性质
于是我们证明了先前解题过程的猜想,证明了我们算法的可行性。
总结
留念一下,在大学也能接触到这种东西,有些感慨。

浙公网安备 33010602011771号