1 条题解

  • 0
    @ 2025-8-24 21:49:59

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 我好蒻呀
    **

    搬运于2025-08-24 21:49:59,当前版本为作者最后更新于2020-02-02 12:36:03,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


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

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

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

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

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

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

    首先有几个性质:

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

      证明: 因为我们有 2Fi=Fi+1+Fi22F_i=F_{i+1}+F_{i-2}

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

      证明: 通过讨论可以知道

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

      +FiFi+1=Fi1+F_i-F_{i+1}=-F_{i-1}

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

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

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

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

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

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

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

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

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

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

    显然,kk 每次至少减少一半,所以答案是 O(logk)\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

    信息

    ID
    2615
    时间
    1000ms
    内存
    512MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者