我刚刚开始进行动态编程,我刚刚在Spoj上尝试了一个基于DP的简单问题。链接 - http://www.spoj.com/problems/MST1/
这是问题陈述 -
在正整数上,您可以执行以下任何一项3 步骤。
1。)从中减去1。 (n = n - 1)
2。)如果它可被2整除,则除以2.(如果n%2 == 0,则n = n / 2)
3。)如果它可被3整除,则除以3.(如果n%3 == 0,则n = n / 3)
给定正整数n并且您的任务是找到最小数量 需要n到1的步骤。
输入:
输入包含整数T(1≤T≤100)个测试用例。 第二行输入是N(0
输出:
对于每种情况,请打印案例编号和最小步骤。
这是我的代码 -
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
// Memo Function returns the smallest number of steps possible for integer a
int memo(int a, int mem[]);
int mem[20000010];
int main() {
int t;
scanf("%i", &t);
for(int i = 1; i <= t; i++) {
int n;
scanf("%i", &n);
memset(mem, -1, sizeof(mem));
mem[1] = 0;
printf("Case %i: %i\n", i, memo(n, mem));
}
return 0;
}
int memo(int a, int mem[]) {
if (mem[a] != -1) return mem[a]; // If the value of smallest steps have already been calculated
int r; // Current Lowest number of steps
r = memo(a - 1, mem) + 1;
if (a % 2 == 0) r = min(r, memo(a/2, mem) + 1);
if (a % 3 == 0) r = min(r, memo(a/3, mem) + 1);
mem[a] = r;
return r;
}
我在互联网和StackOverflow上查找了这个错误,我发现当我们尝试访问尚未分配的内存时可能会发生这种情况,例如访问10个元素数组的第11个元素。但我认为这不是这种情况。
另外,我认为问题的上限是2 * 10 ^ 7,数组也是全局的,所以它应该不是问题。也许我使用memset函数的方式存在一些问题?我真的不知道!
任何帮助将不胜感激!谢谢你的阅读!
答案 0 :(得分:0)
您的DP想法是正确的,但您的代码不适用于大输入(例如1x10 ^ 6,或上边界,2x10 ^ 7)。
通过稍微改变你的代码,你可以预先计算每个答案,然后只输出你感兴趣的答案。由于问题的动态编程方式,即复杂的,它不会非常耗时。问题可以作为一个或多个先前解决的问题的组合来解决。
@post.previous_changes.present? && @post.previous_changes["id"].nil?
我接受了这种方法的接受。
另一个提示:由于您的DP阵列是全局的,因此您不必每次都将其传递给DP功能。