AcWing 1303. 斐波那契前 n 项和

一.题目链接

二.思路

在这里插入图片描述
思路参考:https://www.acwing.com/solution/content/25805/

三.代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 3;

int n, m;
void mul(int c[], int a[], int b[][N])
{
    int temp[N] = {0};
    //一维乘二维 先枚举列
    for(int i = 0; i < N; i ++)
        for(int k = 0; k < N; k ++)//自由变量
        temp[i] = (temp[i] + (LL)a[k] * b[k][i]) % m;
        
    memcpy(c, temp, sizeof temp);//将答案复制过来 此处只能sizeof temp, 不能用c 否则是返还指针的长度
}
void mul(int c[][N], int a[][N], int b[][N])
{
    int temp[N][N] = {0};
    //二维乘二维
    for(int i = 0; i < N; i++)//枚举答案行
        for(int j = 0; j < N; j ++)//枚举答案列
            for(int k = 0; k < N; k ++)//自由变量
            temp[i][j] = (temp[i][j] + (LL)a[i][k] * b[k][j]) % m;
    memcpy(c, temp, sizeof temp);
}
int main()
{
    cin >> n >> m;
    // fn * A = fn+1
    // fn = [fn fn+1 sn]
    int f1[N] = {1, 1, 1};//起始值
    int a[N][N] = {
        {0, 1, 0},
        {1, 1, 1},
        {0, 0, 1}
    };
    
    n --;
    while(n)
    {
        if(n & 1) mul(f1, f1, a);//res = res * a
        mul(a, a, a);//a = a * a;
        n >>= 1;
    }
    cout << f1[2] << endl;
    return 0;
}

四.总结

### AcWing 平台上的动态规划资源 #### 动态规划教程概述 AcWing 提供了一系列针对不同难度级别的动态规划(DP)教程,帮助学习者逐步掌握这一重要算法设计技术。这些课程通常从基础概念出发,介绍状态定义、转移方程构建以及边界条件处理等内容[^2]。 #### 经典题目示例 以斐波那契数列为例,在给定整数`n`的情况下计算第`n`的值是一个典型的入门级DP问题。通过预先设定初始值并利用迭代方式更新后续各数值来解决问题。具体实现如下所示: ```cpp #include <cstdio> const int N = 30; int fib[N]; void solve_fibonacci(int n){ fib[1] = 1; fib[2] = 2; if (n <= 2) { printf("%d\n", fib[n]); return ; } for (int i = 3; i <= n ; ++i ) fib[i] = fib[i - 1] + fib[i - 2]; printf("%d\n",fib[n]); } ``` 此代码片段展示了如何运用自底向上方法解决简单线性递推关系型DP问题。 #### 复杂度更高的案例分析 当面对更复杂的场景时,比如涉及多个阶段决策过程的问题,如石子合并游戏中的最小化总成本策略,则需要考虑更多维度的状态表示形式及其转换逻辑。在这个例子中,为了使最终得分尽可能低,应当优先选择那些能够带来较小增量开销的操作组合[^3]。 例如,如果有三堆石头分别含有数量为 `a`, `b`, `c` 的石子,那么最优方案可能不是直接将两堆合在一起再加第三堆,而是寻找一种顺序使得每次操作产生的额外费用最少。这涉及到对所有可能性进行全面评估,并从中挑选出最佳路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值