简体   繁体   中英

C++ vector and memoization runtime error issues

I encountered a problem here at Codechef. I am trying to use a vector for memoization. As I am still new at programming and quite unfamiliar with STL containers, I have used vector , for the lookup table. (although, I was suggested that using map helps to solve the problem).

So, my question is how is the solution given below running into a run time error. In order to get the error, I used the boundary value for the problem ( 100000000 ) as the input. The error message displayed by my Netbeans IDE is RUN FAILED (exit value 1, total time: 4s) with input as 1000000000 . Here is the code:

#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>

#define LCM 12
#define MAXSIZE 100000000
using namespace std;
/*
 * 
 */
vector<unsigned long> lookup(MAXSIZE,0);

int solve(int n)
{
    if ( n < 12) {
        return n;
    }
    else {
        if (n < MAXSIZE)  {
            if (lookup[n] != 0) {
                return lookup[n];
            }
        }

            int temp = solve(n/2)+solve(n/3)+solve(n/4);
            if (temp >= lookup[n] ) {
                lookup[n] = temp;
            }
            return lookup[n];

    }
}
int main(int argc, char** argv) {
    int t;
    cin>>t;
    int n;
    n = solve(t);
    if ( t >= n) {
        cout<<t<<endl;
    }
    else {
        cout<<n<<endl;
    }
    return 0;
}

I doubt if this is a memory issue because he already said that the program actually runs and he inputs 100000000.

One things that I noticed, in the if condition you're doing a lookup[n] even if n == MAXSIZE (in this exact condition). Since C++ is uses 0-indexed vectors, then this would be 1 beyond the end of the vector.

    if (n < MAXSIZE)  {
     ...
    }

        ...
        if (temp >= lookup[n] ) {
            lookup[n] = temp;
        }
        return lookup[n];

I can't guess what the algorithm is doing but I think the closing brace } of the first "if" should be lower down and you could return an error on this boundary condition.

您要么没有足够的内存,要么没有足够的连续地址空间来存储100,000,000个unsigned long s。

This mostly is a memory issue. For a vector, you need contiguous memory allocation [so that it can keep up with its promise of constant time lookup]. In your case, with an 8 byte double, you are basically requesting your machine to give you around 762 mb of memory, in a single block.

I don't know which problem you're solving, but it looks like you're solving Bytelandian coins. For this, it is much better to use a map, because:

  1. You will mostly not be storing the values for all 100000000 cases in a test case run. So, what you need is a way to allocate memory for only those values that you are actually memoize.
  2. Even if you are, you have no need for a constant time lookup. Although it would speed up your program, std::map uses trees to give you logarithmic look up time. And it does away with the requirement of using up 762 mb contiguously. 762 mb is not a big deal, but expecting in a single block is.

So, the best thing to use in your situation is an std::map. In your case, actually just replacing std::vector<unsigned long> by std::map<int, unsigned long> would work as map also has [] operator access [for the most part, it should].

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM