高精度加法的原理与手工相加类似,只是在计算时需要考虑到进位和处理较大的数字。下面是实现高精度加法的基本原理:
-
表示数字: 高精度加法通常通过字符串来表示数字,因为字符串没有固定长度限制,可以容纳任意大的数字。每个字符代表一个数字位,例如字符串 "123" 表示数字 123。
-
从低位开始逐位相加: 从两个数字的最低位(个位)开始,逐位将对应的数字相加。如果某一数字的位数比另一个少,那么在缺少的位上认为是0。
-
处理进位: 在逐位相加的过程中,需要考虑到进位。如果两个数字相加的结果大于等于10,则需要进位。进位后的结果为当前位相加结果对10取余,而进位值为当前位相加结果除以10的商。
-
从低位到高位计算: 在进行逐位相加时,从低位(个位)开始向高位(十位、百位等)逐渐进行相加。每一位的计算都要考虑上一位的进位值。
-
处理最高位的进位: 当所有位都相加完成后,可能会出现最高位的进位情况。如果最高位相加后需要进位,那么需要在结果的最前面加上一个额外的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;
}
动态规划是一种解决问题的算法思想,它通常用于优化递归或穷举的问题。动态规划的核心思想是将问题分解为子问题,并使用已知的解来解决更大规模的问题,从而避免重复计算。
下面我们以斐波那契数列为例,讲解动态规划的基本原理:
-
定义状态: 首先,我们需要定义问题的状态。在斐波那契数列中,状态通常表示为F(n),表示第n个斐波那契数。
-
确定状态转移方程: 接下来,我们需要确定状态之间的转移关系。在斐波那契数列中,第n个斐波那契数等于前两个斐波那契数的和,即F(n) = F(n-1) + F(n-2)。这就是状态转移方程。
-
确定初始状态: 我们需要确定初始状态,也就是问题的边界条件。在斐波那契数列中,初始状态通常是F(0) = 0和F(1) = 1。
-
利用动态规划求解: 最后,我们利用状态转移方程和初始状态,使用动态规划来求解问题。通常采用自底向上的方法,从初始状态开始,逐步计算出更大规模的状态,直到得到最终的解。
下面是一个使用动态规划来求解斐波那契数列的示例代码:
#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;
}