1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
int memoizationUtil(long int N, long int m, std::vector<std::vector<int>>& dp, const std::vector<long int>& S)
{
if (N < 0) return 0;
if (N == 0) return 1;
if (N > 0 && m <= 0) return 0;
if (dp.at(N-1).at(m-1) != -1) return dp.at(N-1).at(m-1);
dp.at(N-1).at(m-1) = memoizationUtil(N-S.at(m-1), m-1, dp, S) ||
memoizationUtil(N, m-1, dp, S);
return dp.at(N-1).at(m-1);
}
bool memoization(const std::vector<long int>& S, long int N)
{
std::vector<std::vector<int>> dp(N);
for (auto& it : dp)
{
it.assign(S.size(), -1);
}
return (bool)memoizationUtil(N, S.size(), dp, S);
}
bool tabulation(const std::vector<long int>& S, long int N)
{
std::vector<std::vector<bool>> dp(N + 1);
long int m = S.size();
for (auto& it : dp)
{
it.assign(m + 1, false);
}
bool x{false}, y{false};
for (register int i = 0; i <= N; ++i)
{
for (register int j = 0; j <= m; ++j)
{
if (i == 0) dp.at(i).at(j) = true;
else if (j == 0) dp.at(i).at(j) = false;
else
{
if (S.at(j-1) > i) dp.at(i).at(j) = dp.at(i).at(j-1);
if (S.at(j-1) <= i) dp.at(i).at(j) = dp.at(i - S.at(j-1)).at(j-1)
|| dp.at(i).at(j-1);
}
}
}
return dp.at(N).at(m);
}
bool Solve(const std::vector<long int>& S, long int N)
{
if (N & 1) return false; //if N is odd, then no such subset is possible
return memoization(S, N/2); //works fine.
//return tabulation(S, N/2); //gives time out.
}
|