Problem Statement:
Chef has a coin with 1 printed on one side and 2 printed on the other. Chef wants to determine how many different ways he can achieve a sum of S by flipping the coin any number of times.
Approach:
This problem can be approached using dynamic programming or recursion, where the goal is to find all possible sequences of coin flips that sum up to S. The recursive nature of the problem can be observed by noting that if we know the number of ways to achieve a sum S-1 and S-2, we can easily compute the number of ways to achieve S.
Recursive Approach:
-
Base Cases:
- If
S < 0, there is no valid sequence of flips that can sum toS, so we return0. - If
S == 0, there is exactly one way to achieve the sum0—by not flipping the coin at all. So, we return1.
- If
-
Recursive Case:
- To achieve a sum
S, the last coin flip must either be1or2. - If the last flip is
1, the problem reduces to finding the number of ways to achieve a sum ofS-1. - If the last flip is
2, the problem reduces to finding the number of ways to achieve a sum ofS-2. - Therefore, the total number of ways to achieve
Sis the sum of the ways to achieveS-1andS-2.
- To achieve a sum
Note : For the given constraint, recursive approach is enough to pass the tests.
Complexity:
- Time Complexity: The time complexity of this recursive solution is
O(2^S), which is exponential. This is because each call tocountWays(S)makes two additional calls to smaller subproblems. While simple, this approach can be highly inefficient for large values ofS.
Space Complexity:
- Space Complexity: The space complexity is
O(S)due to the depth of the recursive call stack.
Optimization with Dynamic Programming:
To optimize the solution, we can use dynamic programming to avoid redundant calculations by storing the results of subproblems:
#include<bits/stdc++.h>
using namespace std;
// Memoization table to store results of subproblems
unordered_map<int, int> dp;
int countWays(int S) {
// Base cases
if (S < 0) return 0; // No way to achieve a negative sum
if (S == 0) return 1; // One way to achieve sum 0 (by not flipping any coins)
// Check if the result is already in the memoization table
if (dp.find(S) != dp.end()) return dp[S];
// Recursively calculate the number of ways to achieve sum S
dp[S] = countWays(S - 1) + countWays(S - 2);
return dp[S];
}
int main() {
int S;
cin >> S;
cout << countWays(S) << endl; // Output the result
return 0;
}
- This top-down approach with memoization is much more efficient than a naive recursive solution. It ensures that each subproblem is solved only once, reducing the time complexity to
O(S).