SIGSEGV动态编程错误 - CodeChef

时间:2015-12-18 18:09:14

标签: c++ dynamic-programming sigsegv

希望你们都过得愉快!

我喜欢编程,但过去几天我一直在不眠之夜,CodeChef总是在我的动态编程解决方案中返回SIGSEGV错误。

我现在正在解决this问题。这是问题 -

  

在Byteland,他们有一个非常奇怪的货币体系。每个Bytelandian   金币上写有整数。一枚硬币可以   在银行交换成三个硬币:n / 2,n / 3和n / 4。但是这些   数字全部向下舍入(银行必须赚钱)。您   也可以出售美元的Bytelandian硬币。找的零钱   费率是1:1。但你不能买Bytelandian硬币。你有一枚金币   硬币。您可以获得的最高美元金额是多少?   它?

     

输入

     

输入将包含多个测试用例(不超过10个)。每   testcase是一个数字为n,0 <= n <= 1 000 000 000的单行   是你硬币上写的数字。输出

     

对于每个测试用例输出一行,包含最大量   你可以赚到的美元。实施例

     

输入:12 2

     

输出:13 2您可以将12更改为6,4和3,然后更改这些   进入$ 6 + $ 4 + $ 3 = $ 13。如果你尝试将硬币2换成3个较小的硬币   硬币,你会得到1,0和0,之后你可以得到不超过1美元   他们。最好将2硬币直接更改为2美元。

现在我知道这很容易。当我宣布一个10 ^ 9整数长的数组(超过1GB的内存......哇!)时,我确实陷入困境,但回到我的感官 - 我决定做记忆直到10001,并在那个简单的递归之后。但仍然 - 我犯了一个错误,而且它给出了SIGSEGV错误。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

long long n[100001];

long long calc(long long x) {
    if (x < 10001) {
        if(n[x] != 0) return n[x];
        n[x] = max(x, calc(x/2) + calc(x/3) + calc(x/4));
        return n[x];
    }
    else return max(x, calc(x/2) + calc(x/3) + calc(x/4));
}

int main() {
    memset(n, 0, sizeof(n));
    n[1] = 1;
    n[2] = 2;
    n[3] = 3;
    n[4] = 4;
    n[5] = 5;
    n[6] = 6;
    for (int i = 7; i < 10001; i++)
        n[i] = calc(i);
    int t = 10;
    while (t--) {
        long long c;
        scanf("%lld", &c);
        printf("%lld\n", calc(c));
    }
    return 0;
}

我也解决了之前的一些问题 - 所有这些问题都给了我一两次错误。我知道这个错误意味着我正在尝试访问尚未分配的内存,但是我的方法有什么问题我总是得到这个错误?

1 个答案:

答案 0 :(得分:0)

  

问题在于拐角情况n = 0。

calc(0)无限地递归,因为0 <10001且n [0] = 0。您需要添加calc(0)= 0的终止条件。

外卖:

  • 请务必检查您的编程竞赛解决方案。
  • 始终确保您的递归不会导致无限循环。