1 条题解

  • 0
    @ 2026-9-26 10:57:47

    给定正整数 kk,求用斐波那契数的和或差表示 kk 所需要的斐波那契数数量最小值。

    k≤4×107k \leq 4\times 10^7

    时空限制:1s/125MB\texttt{1s/125MB}

    题解界面 LaTeX 渲染可能会有点问题,建议到博客中查看:题解 P3539 【[POI2012]ROZ-Fibonacci Representation】

    这题的贪心做法是这样的:每次找到一个离 kk 最近的斐波那契数 FiF_i,令 k←∣k−Fi∣k\leftarrow|k-F_i|,重复若干次直到 k=0k=0。(即每次令 k←min⁡∣k−Fi∣k \leftarrow \min|k-F_i|)

    但是我在网上一直找不到比较好的证明,非常自闭QAQ。

    首先有几个性质:

    • 存在最优方案,不会选择重复的一项。

      证明: 因为我们有 2Fi=Fi+1+Fi−22F_i=F_{i+1}+F_{i-2}。

    • 存在最优方案,不会选择相邻的两项。

      证明: 通过讨论可以知道

      +Fi+Fi+1=+Fi+2+F_i+F_{i+1}=+F_{i+2}

      +Fi−Fi+1=−Fi−1+F_i-F_{i+1}=-F_{i-1}

      −Fi+Fi+1=+Fi−1-F_i+F_{i+1}=+F_{i-1}

      −Fi−Fi+1=−Fi+2-F_i-F_{i+1}=-F_{i+2}

    • 若当前 Fi≤k≤Fi+1F_i \leq k \leq F_{i+1},那么存在最优方案,一定包含了 FiF_i 或 Fi+1F_{i+1}。

      证明: 反证法。假设不包含 FiF_i 和 Fi+1F_{i+1}。那么根据不选相邻和重复的原则,我们可以证明其他部分的斐波那契数通过加减一定无法凑到 [Fi,Fi+1][F_i,F_{i+1}] 内的数。具体地,我们有 Fi−1+Fi−3+⋯<FiF_{i-1}+F_{i-3}+\cdots<F_i 成立,这是因为 F1+F3+⋯+F2n−1=F2n−1F_1+F_3+\cdots +F_{2n-1}=F_{2n}-1 和 F2+F4+⋯+F2n=F2n+1−1F_2+F_4+\cdots +F_{2n}=F_{2n+1}-1(为方便设 F1=1,F2=2F_1=1,F_2=2)。

      这样一来,F1∼Fi−1F_1\sim F_{i-1} 的数里选出来的和 S<FiS<F_i。同样我们如果用比 Fi+1F_{i+1} 大的数拿去减,也会遇到这种的情况: Fi+2−S>Fi+1F_{i+2}-S>F_{i+1} ,并且因为不能选相邻的,Fi+4−Fi+2>Fi+3F_{i+4}-F_{i+2}>F_{i+3} 也是没用的。

      因此我们就证明了,存在最优方案,一定包含了 FiF_i 或 Fi+1F_{i+1}。

    那么接下来,我们就得到了,若当前 Fi≤k≤Fi+1F_{i}\leq k \leq F_{i+1},我们一定要从 Fi,Fi+1F_i,F_{i+1} 中选一个。

    接下来我们归纳证明,一定是选较近的那个斐波那契数:

    • 显然对于满足 k<F3k < F_3 的 kk,结论成立。
    • 假设对于满足 k<Fik < F_i 的 kk,结论是成立的,那么接下来考虑证明对于满足 Fi≤k<Fi+1F_i\leq k<F_{i+1} 的 kk,有结论成立。不妨假设 k−Fi=ak-F_i=a,Fi+1−k=bF_{i+1}-k=b,不失一般性地,设 a<ba<b,对于 a>ba>b 同理。
    • 接下来证明令 k←ak\leftarrow a 的策略不比 k←bk \leftarrow b 的策略劣。首先有 a+b=Fi+1−Fi=Fi−1a+b=F_{i+1}-F_{i}=F_{i-1}。根据 a<ba<b 我们有 b∈(Fi−12,Fi−1]b\in (\frac{F_{i-1}}2,F_{i-1}],并且因为 Fi−3<Fi−12<Fi−2<Fi−1F_{i-3}<\frac{F_{i-1}}{2}<F_{i-2}<F_{i-1},而 Fi−12=Fi−2+Fi−32\frac{F_{i-1}}2=\frac{F_{i-2}+F_{i-3}}2,因此离 bb 最近的斐波那契数一定是 Fi−2,Fi−1F_{i-2},F_{i-1} 之一。
    • 因为 b≤Fi−1<Fib \leq F_{i-1}<F_i 满足一定选离 bb 较近的斐波那契数,因此我们有 bb 的最优表示中一定有 Fi−2,Fi−1F_{i-2},F_{i-1} 之一。那么 a=Fi−1−ba=F_{i-1}-b,所以 aa 可以由 bb 的表达转化过来,并且 Fi−1F_{i-1} 可以和 bb 的表示中的 Fi−2F_{i-2} 或是 Fi−1F_{i-1} 合并/抵消,因此 aa 均能得到一种不劣于 bb 的表达方式。

    至此我们证明了贪心策略的正确性。

    显然,kk 每次至少减少一半,所以答案是 O(log⁡k)\mathcal O(\log k) 级别的,这也是时间复杂度的级别。

    #include <bits/stdc++.h>
    
    typedef long long s64; 
    
    const s64 lim = 4e17; 
    
    int main()
    {
    	static s64 f[10001];
    	
    	int m = 2; 
    	f[1] = 1, f[2] = 2; 
    	while (f[m] <= lim)
    	{
    		++m; 
    		f[m] = f[m - 2] + f[m - 1]; 
    	}
    
    	int orzczk; 
    	std::cin >> orzczk; 
    	while (orzczk--)
    	{
    		s64 n; 
    		int res = 0; 
    		std::cin >> n; 
    		while (n)
    		{
    			++res; 
    			int suf = std::upper_bound(f + 1, f + m + 1, n) - f; 
    			n = std::min(f[suf] - n, n - f[suf - 1]); 
    		}
    		std::cout << res << '\n'; 
    	}
    	return 0; 
    }
    
    • 1

    [POI 2012] ROZ-Fibonacci Representation斐波那契表示法

    信息

    ID
    4461
    时间
    100ms
    内存
    164MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者