高精度加法和动态规划综合运用

高精度加法的原理与手工相加类似,只是在计算时需要考虑到进位和处理较大的数字。下面是实现高精度加法的基本原理:

  1. 表示数字: 高精度加法通常通过字符串来表示数字,因为字符串没有固定长度限制,可以容纳任意大的数字。每个字符代表一个数字位,例如字符串 "123" 表示数字 123。

  2. 从低位开始逐位相加: 从两个数字的最低位(个位)开始,逐位将对应的数字相加。如果某一数字的位数比另一个少,那么在缺少的位上认为是0。

  3. 处理进位: 在逐位相加的过程中,需要考虑到进位。如果两个数字相加的结果大于等于10,则需要进位。进位后的结果为当前位相加结果对10取余,而进位值为当前位相加结果除以10的商。

  4. 从低位到高位计算: 在进行逐位相加时,从低位(个位)开始向高位(十位、百位等)逐渐进行相加。每一位的计算都要考虑上一位的进位值。

  5. 处理最高位的进位: 当所有位都相加完成后,可能会出现最高位的进位情况。如果最高位相加后需要进位,那么需要在结果的最前面加上一个额外的1作为最高位。

通过以上原理,我们可以实现一个高精度加法的算法,来对两个较大的数字进行相加,而不会出现溢出问题。

模板如下,要注意得到的数是最高位放后面;如123会被存为321,所以要逆序输出。

vector<int> add(vector<int> &A, vector<int> &B)  // C = A + B, A >= 0, B >= 0
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i++) {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}

逆序输出

vector<int> h = count(n);
    for (auto it=h.rbegin();it!=h.rend(); it++) {
        cout << *it;
    }

动态规划是一种解决问题的算法思想,它通常用于优化递归或穷举的问题。动态规划的核心思想是将问题分解为子问题,并使用已知的解来解决更大规模的问题,从而避免重复计算。

下面我们以斐波那契数列为例,讲解动态规划的基本原理:

  1. 定义状态: 首先,我们需要定义问题的状态。在斐波那契数列中,状态通常表示为F(n),表示第n个斐波那契数。

  2. 确定状态转移方程: 接下来,我们需要确定状态之间的转移关系。在斐波那契数列中,第n个斐波那契数等于前两个斐波那契数的和,即F(n) = F(n-1) + F(n-2)。这就是状态转移方程。

  3. 确定初始状态: 我们需要确定初始状态,也就是问题的边界条件。在斐波那契数列中,初始状态通常是F(0) = 0和F(1) = 1。

  4. 利用动态规划求解: 最后,我们利用状态转移方程和初始状态,使用动态规划来求解问题。通常采用自底向上的方法,从初始状态开始,逐步计算出更大规模的状态,直到得到最终的解。

下面是一个使用动态规划来求解斐波那契数列的示例代码:

 

#include <iostream>
using namespace std;

long long fibonacci(int n) {
    if (n <= 1) return n;
    long long dp[n+1];
    dp[0] = 0;
    dp[1] = 1;
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[n];
}

int main() {
    int n;
    cout << "Enter the value of n: ";
    cin >> n;
    cout << "The " << n << "th Fibonacci number is: " << fibonacci(n) << endl;
    return 0;
}

在这个示例中,我们使用动态规划来求解斐波那契数列的第n个数。我们定义了一个数组dp来存储斐波那契数列的值,然后利用状态转移方程dp[i] = dp[i-1] + dp[i-2]逐步计算出第n个数的值。

题目描述

楼梯有 N 阶,上楼可以一步上一阶,也可以一步上二阶。

编一个程序,计算共有多少种不同的走法。

输入格式

一个数字,楼梯数。

输出格式

输出走的方式总数。

输入输出样例

输入 

4

输出 #1复制

5

说明/提示

  • 对于 60% 的数据,1≤N≤50;
  • 对于 100% 的数据,1≤N≤5000。

 

ac代码

#include <bits/stdc++.h>

using namespace std;
vector<vector<int>> rmb(5002);


vector<int> add(vector<int> &A, vector<int> &B)  // C = A + B, A >= 0, B >= 0
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i++) {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}

vector<int> count(int n) {
    if (n == 1)return {1};
    if (n == 2)return {2};
    rmb[1] = {1};
    rmb[2] = {2};
    for (int i = 3; i <= n; i++) {
        rmb[i] = add(rmb[i - 1], rmb[i - 2]);
    }
    return rmb[n];
}

int main() {
    int n = 0, sum = 0;
    cin >> n;
    vector<int> h = count(n);
    for (auto it=h.rbegin();it!=h.rend(); it++) {
        cout << *it;
    }
    return 0;
}

  • 80
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小宇宙中微子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值