编写一个main函数对以下代码进行测试:long memo[1000000]; // 定义备忘录数组 long f(int n) { if (n == 1) return 1; if (n == 2) return 2; if (memo[n] != 0) return memo[n]; // 如果已经计算过,直接返回备忘录中的值 long sum = 1; for (int i = 1; i <= n - 1; i++) sum += f(i); memo[n] = sum; // 将计算结果存入备忘录中 return sum; }
时间: 2024-01-25 15:03:01 浏览: 131
好的,以下是对该代码进行测试的 main 函数:
```cpp
#include <iostream>
using namespace std;
long memo[1000000]; // 定义备忘录数组
long f(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
if (memo[n] != 0) return memo[n]; // 如果已经计算过,直接返回备忘录中的值
long sum = 1;
for (int i = 1; i <= n - 1; i++) sum += f(i);
memo[n] = sum; // 将计算结果存入备忘录中
return sum;
}
int main() {
int n;
cout << "请输入斐波那契数列的项数:";
cin >> n;
cout << "斐波那契数列的前" << n << "项为:";
for (int i = 1; i <= n; i++) {
cout << f(i) << " ";
}
return 0;
}
```
你可以将以上代码保存为一个 C++ 文件,然后编译并运行它来测试给定的斐波那契数列计算代码。这个程序会要求你输入斐波那契数列的项数,然后输出对应的前 n 项斐波那契数列。在这个版本的代码中,我们使用了备忘录 memo 来存储已经计算过的斐波那契数,避免了重复计算。
相关问题
解释代码int[][] memo; int numTrees(int n) { // 备忘录的值初始化为 0 memo = new int[n + 1][n + 1]; return count(1, n); } int count(int lo, int hi) { if (lo > hi) return 1; // 查备忘录 if (memo[lo][hi] != 0) { return memo[lo][hi]; } int res = 0; for (int mid = lo; mid <= hi; mid++) { int left = count(lo, mid - 1); int right = count(mid + 1, hi); res += left * right; } // 将结果存入备忘录 memo[lo][hi] = res; return res; }
这段代码实现了一个递归函数numTrees,用于计算n个节点的二叉搜索树的数量。为了避免重复计算,使用了备忘录memo来保存已经计算过的结果。
具体来说,函数count(lo, hi)用于计算从lo到hi的节点构成的二叉搜索树的数量。如果lo>hi,则返回1,因为空树也算一棵树。如果备忘录memo中已经有了这个范围的计算结果,则直接返回结果。否则,对于每个mid(即根节点),计算左右子树的数量,然后将左右子树的数量相乘,即可得到以mid为根节点的二叉搜索树的数量。最后,将所有以不同节点为根节点的二叉搜索树的数量相加,得到从lo到hi的节点构成的所有二叉搜索树的数量。同时,将这个结果存入备忘录memo中,以便后续使用。
在函数numTrees中,先将备忘录memo初始化为0,然后调用count(1, n)计算n个节点构成的所有二叉搜索树的数量。
int[] memo; int coinChange(int[] coins, int amount) { memo = new int[amount + 1]; // 备忘录初始化为⼀个不会被取到的特殊值,代表还未被计算 Arrays.fill(memo, -666);return dp(coins, amount); } int dp(int[] coins, int amount) { if (amount == 0) return 0; if (amount < 0) return -1; // 查备忘录,防⽌重复计算 if (memo[amount] != -666) return memo[amount]; int res = Integer.MAX_VALUE; for (int coin : coins) { // 计算⼦问题的结果 int subProblem = dp(coins, amount - coin); // ⼦问题⽆解则跳过 if (subProblem == -1) continue; // 在⼦问题中选择最优解,然后加⼀ res = Math.min(res, subProblem + 1); } // 把计算结果存⼊备忘录 memo[amount] = (res == Integer.MAX_VALUE) ? -1 : res; return memo[amount]; }
这段代码实现的是使用动态规划算法解决零钱兑换问题。其中,memo数组是备忘录,用于记录已经计算过的子问题的结果,避免重复计算。具体实现步骤如下:
1. 初始化memo数组为一个不会被取到的特殊值,代表还未被计算。
2. 调用dp函数,传入coins数组和amount金额。
3. 如果amount为0,直接返回0;
4. 如果amount小于0,说明当前组合不可行,返回-1;
5. 查备忘录,如果memo[amount]不等于特殊值,说明已经计算过,直接返回memo[amount]。
6. 初始化res为最大值,遍历coins数组。
7. 对于每个coin,通过递归调用dp函数计算子问题的结果subProblem。
8. 如果子问题无解,则跳过当前coin,继续遍历下一个coin。
9. 在子问题中选择最优解,然后加1,更新res。
10. 将计算结果存入备忘录memo[amount]中。
11. 返回memo[amount]作为当前组合的最优解。
该算法的时间复杂度为O(amount*N),其中N为coins数组的长度。由于使用了备忘录,避免了重复计算,因此该算法的空间复杂度为O(amount)。
阅读全文