每日一题:最多的方案

题目链接:https://www.luogu.com.cn/problem/P4133

题目描述:

现在给一个正整数n,它可以写成一些斐波那契数的和的形式。如果我们要求不同的方案中不能有相同的斐波那契数,那么对一个n最多可以写出多少种方案呢?

输入格式:只有整数n.

输出格式:输出组成n的方案数.

解题思路:记录小于等于n的斐波那契数,并用dp数组对其进行分解.

具体代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
////对于n的范围到110的斐波那契数的和是大于1e8的
const int MaxN = 110;
int main()
{   ll n;
    vector<ll>f(MaxN);
    int m=0,cnt=0;
    vector<int>pos(MaxN);
    vector<vector<int>>g(MaxN,vector<int>(2));
    cin >> n;

    ////生成斐波拉契数列(仅归纳小于等于n的)
    f[1] = 1, f[2] = 2;
    for (m = 3; f[m - 1] <= n; ++m)
        f[m] = f[m - 1] + f[m - 2];
    --m;

////从最大的斐波拉契数开始分解n,并记录能分解的数的位置
    for (int i = m; i >= 1; --i)
        if (n >= f[i])
        {
            n -= f[i];
            pos[++cnt] = i;
        }
    std::sort(pos.begin()+1, pos.begin()+cnt+1);

    ////构建dp数组以及分解大的斐波那契数
    g[1][1] = 1, g[1][0] = pos[1] - 1 >> 1;
    for (int i = 2; i <= cnt; ++i)
    {   g[i][1] = g[i - 1][0] + g[i - 1][1];
        g[i][0] = g[i - 1][1] * (pos[i] - pos[i - 1] - 1 >> 1) + g[i - 1][0] * (pos[i] - pos[i - 1] >> 1);
    }

    printf("%d\n", g[cnt][0] + g[cnt][1]);

    return 0;
}

posted on 2025-01-27 11:25  神奇猫猫侠  阅读(8)  评论(0编辑  收藏  举报

导航