I am trying to implement an approach using memoization for calculating the nth Fibonacci number.
#include <iostream>
#include <vector>
using namespace std;
int fib(int n, vector<int> v) {
int result = 0;
if (v[n] != 0) {
return v[n];
}
if (n == 1 || n == 2) {
result = 1;
}
else {
result = fib(n - 1, v) + fib(n - 2, v);
}
v[n] = result;
return result;
}
int main()
{
int n = 12;
vector<int> v(n + 1, 0);
cout << fib(n, v);
}
However, I get this error.
runtime error: addition of unsigned offset to 0x602000000110 overflowed to 0x60200000010c (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:34
How do I change the solution to resolve this problem? Thanks!
You are copying the vector for each call, so you don't fill initial the vector by numbers.
You have to use unsigned long long to calculate more numbers (actually 93 of them). int can fit only 46 (1836311903).
I would check the vector size inside of the function instead of creating it outside.
Use
unsigned long long fib(int n, vector <unsigned long long> &v) {
Full code: https://ideone.com/3Ipjgo
#include <iostream>
#include <vector>
using namespace std;
unsigned long long fib(int n, vector <unsigned long long> &v)
{
if (v.size() <= n)
v.resize(n + 1);
if (v[n])
return v[n];
return v[n] = n <= 2 ? 1 : fib(n - 1, v) + fib(n - 2, v);
}
int main()
{
vector <unsigned long long> v;
cout << fib(12, v) << endl;
for (int q=1; q<=94; ++q)
cout << q << ' ' << fib(q, v) << endl;
return 0;
}
Related
I stuck at a problem SPOJ.
I checked all the test cases passing all of them, but I am still getting "WA" on spoj.
I know it can be solved using dynamic programming, but I am practicing memoization.
Here is my code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector <int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}
Test case 1:
5
1 2 3 4 5
Test case 2:
1
10
output 1:
9
output 2:
10
You are using wrong data type to store value in vector dp.
As the sum of coins can go up to (10^9*10^2=10^11) therefore int would not be able to store it .Try using long long int instead as it would not lead to overflow condition.
SAME CODE AS YOURS(using long long int got accepted):
USE: vector< long long int>dp(1000000)
ACCEPTED CODE:
#include<iostream>
#include<vector>
#include<algorithm>
#define ull unsigned long long
using namespace std;
vector <long long int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}
The full explanation of the problem is here---http://imgur.com/a/UiE7L .
I've written the code, but it is showing segmentation error which I'm not able to solve. As per the logic of the program, I am saving the minimum number of operations needed to reach number n on the nth position of the array. I intend to go by this logic.
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
long long f(long long n, vector <long long> arr)
{
arr[1]=0;
arr.push_back(n);
long long ans=0, ret=0;
if (n==1)
{
return (0);
}
ans= f(n-1, arr) + 1;
if (n%2==0)
{
ret= f(n/2, arr) + 1;
if (ret<ans)
{
ans=ret;
std::cout<<ans<<'\n';
}
}
if (n%3==0)
{
ret= f(n/3, arr) + 1;
if (ret<ans)
{
ans=ret;
std::cout<<ans<<'\n';
}
}
arr[n]=ans;
return arr[n];
}
int main() {
long long n;
std::cin >> n;
std::vector<long long> arr;
std::cout<<f(n, arr);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
long long f(long long n, vector <long long> arr)
{
arr[1]=0;
//arr.push_back(n); // not required
long long ans=0, ret=0;
if (n==1)
{
return (0);
}
ans= f(n-1, arr) + 1;
if (n%2==0)
{
ret= f(n/2, arr) + 1;
if (ret<ans)
{
ans=ret;
//std::cout<<ans<<'\n';
}
}
if (n%3==0)
{
ret= f(n/3, arr) + 1;
if (ret<ans)
{
ans=ret;
//std::cout<<ans<<'\n';
}
}
arr[n]=ans;
return arr[n];
}
int main() {
long long n = 120;
std::vector<long long> arr(n+1); // declare arr with size n+1
std::cout<<f(n, arr);
return 0;
}
You have accessed a[1] without declaring size of array >= 2 as array in c++ is 0 indexing and in addition to that if you provide array with some initial size as arr(n+1) while declaring then no need to push value of n in arr again.
then your solution works correct.
for itterative approach
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n;
cin >> n;
vector<long long> arr(n+1);
for (int i = 1; i <= n; i++) {
arr[i] = arr[i - 1] + 1;
if (i % 2 == 0) arr[i] = min(1 + arr[i / 2], arr[i]);
if (i % 3 == 0) arr[i] = min(1 + arr[i / 3], arr[i]);
}
cout << arr[n]-1 << endl;
return 0;
}
I have been struggling with this problem http://www.spoj.com/problems/PRIME1/ and if anyone can help me finding the error in my code. I have used segmented sieve of eratosthenes and I have also looked through a lot of online resources but somehow I am getting a runtime error on spoj.
Thanks
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <cstdlib>
#include <cassert>
#define fora(i,a,b) for(i = a; i < b; i++)
#define fin(f) freopen(f, "r", stdin)
#define fout(f) freopen(f, "w", stdout)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
typedef vector<bool> vb;
const ll LIMIT = 1000000000;
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
vb is_prime(range+1, true);
vb seg_primes(segment_size+1, true);
vi prime;
range = floor(sqrt((double)n));
fora (i, 2, range+1)
if (is_prime[i]) {
for (j = i*2; j <= range; j+=i)
is_prime[j] = false;
}
fora (i, 2, range+1)
if (is_prime[i] == 1)
prime.push_back(i);
fora (i, 0, prime.size()) {
p = prime[i];
s = m/p;
s *= p;
for (j = s; j <= n; j+=p) {
if (j < m) continue;
seg_primes[j-m] = false;
}
}
fora (i, 0, prime.size())
if (prime[i] >= m && prime[i] <= n) {
cout << prime[i] << endl;
}
fora (i, 0, n-m+1)
if (seg_primes[i] && (i+m) != 1) {
cout << i+m << endl;
}
}
int main()
{
int segment_size = 100000;
// fin("input.in");
int t;
cin >> t;
while (t--) {
ll a, b;
cin >> a >> b;
if (a > b)
segmentedSieve(a, b, segment_size);
else
segmentedSieve(b, a, segment_size);
if (t != 0)
cout << endl;
}
}
It seems range is uninitialized here:
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
vb is_prime(range+1, true); // uninitialized range... !!
maybe you want
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p, range;
range = floor(sqrt((double)n)); // This first...
vb is_prime(range+1, true); // then this
When possible you should initialize variables when you define them.
void segmentedSieve(ll n, ll m, int segment_size) {
int i, j, s, p; // no range here
int range = floor(sqrt((double)n)); // This first...
vb is_prime(range+1, true); // then this
In general you should postpone the definition of variables until you need them, i.e. don't define all variables in the start but do it as you need them.
p.s. As others have commented already - get rid of all that macro stuff...
Let A be a vector of vectors of type double, i.e. vector<vector<double> > A and B be the same but for integers, i.e. vector<vector<int> > B. Assume that size of A and B is the same (and sizes of every nested vectors are equal as well).
I would like to check if j is contained in i-th vector of B by using std::find, so I write std::find(B[i].begin(), B[i].end(), j) != B[i].end(). Now, if that is true I would like to return value in A corresponding to [i][position_of_j_found_in_B[i]]. How can I accomplish this?
My code is as follows:
class SparseMatrix
{
private:
vector<vector<double> > entries_;
vector<vector<int> > columnIndices_;
public:
SparseMatrix();
SparseMatrix(vector<vector<double> >,vector<vector<int> >);
~SparseMatrix();
// getters
vector<vector<double> > getEntries();
vector<vector<int> > getColIndices();
double operator()(const unsigned int&, const unsigned int&);
vector<int> size();
};
SparseMatrix::SparseMatrix() { };
SparseMatrix::SparseMatrix(vector<vector<double> > values, vector<vector<int> > colInd) : entries_(values), columnIndices_(colInd) { };
SparseMatrix::~SparseMatrix() { };
vector<vector<double> > SparseMatrix::getEntries() { return entries_; }
vector<vector<int> > SparseMatrix::getColIndices() { return columnIndices_; }
double SparseMatrix::operator()(const unsigned int i, const unsigned int j)
{
assert(i <= (*this).size()[0] && j <= (*this).size()[1]);
auto it = find(columnIndices_[i].begin(),columnIndices_[i].end(), j);
if(it != columnIndices_[i].end())
return entries_[i][it - columnIndices_[i].begin()];
return 0.0;
}
vector<int> SparseMatrix::size() // returns dimensions of the matrix
{
vector<int> dim(2); // stores dimensions of the matrix
dim[0] = columnIndices_.size(); // numbers of rows in a matrix
int temp = 0;
vector<vector<int> >::iterator i;
for(i=columnIndices_.begin(); i != columnIndices_.end(); ++i)
{
if(*max_element((*i).begin(),(*i).end()) > temp) // if maximal element in i-th vector of columnIndices_ is greater then current (temp)
temp = *max_element((*i).begin(),(*i).end()); // update current biggest with new one
}
dim[1] = temp;
return dim;
}
And my main() function is
int main(int argc, char const *argv[])
{
vector<vector<double> > values {{3.0, 1.0}, {2.0}, {5.0, 4.0}};
vector<vector<int> > columns {{1,3}, {1}, {2,3}};
SparseMatrix A(values,columns);
cout << "Matrix A has dimensions " << A.size()[0] << "x" << A.size()[1] << "." << endl; // works fine
cout << A.getEntries()[0][0] << " " << A(0,0) << endl; // I expect the same output...
return 0;
}
Here is solution the solution of original problem:
double foo(const vector<vector<double> >& X, const vector<vector<int> >& Y, unsigned int i, unsigned int j)
{
auto it = find(Y[i].begin(),Y[i].end(), j);
if (it != Y[i].end())
return X[i][it - Y[i].begin()];
return 0.0;
}
P.S. I pass vector by reference because for optimization, for the same reason I pass unsigned int by value.
Here is example of SparseMatrix implementation:
#include <cassert>
#include <vector>
#include <tuple>
#include <iostream>
#include <cmath>
#include <algorithm>
class SparseMatrix final {
public:
explicit SparseMatrix(const std::vector<double>& full_matrix) {
static constexpr double EPS = 1e-16;
const size_t N = std::sqrt(full_matrix.size());
assert((N * N) == full_matrix.size());
for (size_t i = 0; i < N; ++i)
for (size_t j = 0; j < N; ++j)
if (std::fabs(full_matrix[i * N + j]) > EPS)
data_.push_back(std::make_tuple(full_matrix[i * N + j], i, j));
}
double operator()(size_t i, size_t j) const {
auto it = std::find_if(data_.begin(), data_.end(),
[&i, &j](const std::tuple<double, size_t, size_t>& elm) {
return std::get<1>(elm) == i && std::get<2>(elm) == j;
});
return it == data_.end() ? 0.0 : std::get<0>(*it);
}
private:
std::vector<std::tuple<double, size_t, size_t>> data_;
};
int main()
{
SparseMatrix A({3.0, 0, 1.0,
2.0, 0, 0,
0, 5.0, 4.0});
std::cout << A(0, 0) << '\n';
}
Note this SparseMatrix good for study projects, but for every day usage,
the best way to use already existing classes for linear algebra for C++.
My code is in
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <vector>
#include <cmath>
using namespace std;
struct State {
int v;
const State *rest;
void dump() const {
if(rest) {
cout << ' ' << v;
rest->dump();
} else {
cout << endl;
}
}
State() : v(0), rest(0) {}
State(int _v, const State &_rest) : v(_v), rest(&_rest) {}
};
void ss(int *ip, int *end, int target, const State &state) {
if(target < 0) return; // assuming we don't allow any negatives
if(ip==end && target==0) {
state.dump();
return;
}
if(ip==end)
return;
{ // without the first one
ss(ip+1, end, target, state);
}
{ // with the first one
int first = *ip;
ss(ip+1, end, target-first, State(first, state));
}
}
vector<int> get_primes(int N) {
int size = floor(0.5 * (N - 3)) + 1;
vector<int> primes;
primes.push_back(2);
vector<bool> is_prime(size, true);
for(long i = 0; i < size; ++i) {
if(is_prime[i]) {
int p = (i << 1) + 3;
primes.push_back(p);
// sieving from p^2, whose index is 2i^2 + 6i + 3
for (long j = ((i * i) << 1) + 6 * i + 3; j < size; j += p) {
is_prime[j] = false;
}
}
}
}
int main() {
int N;
cin >> N;
vector<int> primes = get_primes(N);
int a[primes.size()];
for (int i = 0; i < primes.size(); ++i) {
a[i] = primes[i];
}
int * start = &a[0];
int * end = start + sizeof(a) / sizeof(a[0]);
ss(start, end, N, State());
}
It takes one input N (int), and gets the vector of all prime numbers smaller than N.
Then, it finds the number of unique sets from the vector that adds up to N.
The get_primes(N) works, but the other one doesn't.
I borrowed the other code from
How to find all matching numbers, that sums to 'N' in a given array
Please help me.. I just want the number of unique sets.
You've forgotten to return primes; at the end of your get_primes() function.
I'm guessing the problem is:
vector<int> get_primes(int N) {
// ...
return primes; // missing this line
}
As-is, you're just writing some junk here:
vector<int> primes = get_primes(N);
it's undefined behavior - which in this case manifests itself as crashing.