Editorial
# 1. Problem Understanding
- Given a row of coins with specified values, the task is to select a subset such that no two chosen coins are adjacent.
- Additionally, the sum S of the selected coins must be divisible by a given integer k.
- The objective is to maximize S. If no valid selection exists, output -1.
# 2. Approach
- A dynamic programming (DP) strategy is used to simultaneously handle the non-adjacency constraint and the modulo requirement.
- The DP state is designed to track the current coin index, the current remainder modulo k of the selected coins, and whether the previous coin was selected.
# 3. DP State and Transitions
- The state is defined using two arrays:
• dp0[r]: the maximum sum with remainder r when the previous coin was not selected.
• dp1[r]: the maximum sum with remainder r when the previous coin was selected.
- When the previous coin was not selected (dp0), you have two options:
• Skip the current coin, retaining dp0[r].
• Select the current coin: update the remainder to (r + coins[i]) mod k, add the coin's value, and move to dp1.
- When the previous coin was selected (dp1), the current coin must be skipped, so the state transitions to dp0.
# 4. Base Case
- Initially, no coin has been selected, so start with dp0[0] = 0, representing a sum of 0 with a remainder of 0.
# 5. Final Result
- After processing all coins, the answer is the maximum sum among the states with remainder 0 (from either dp0 or dp1).
- If no such state is valid (i.e., the maximum sum remains negative), the output is -1.
# 6. Time and Space Complexity
- The algorithm processes roughly 2 * n * k states, where n is the number of coins and k is the modulus.
- Each state update is done in constant time, leading to an overall time complexity of O(n * k).
- Although the space complexity is also O(n * k) in a straightforward implementation, it is optimized here by using only two arrays (dp0 and dp1) for state reduction, so the actual complexity is O(k).
Author's Solution
GNU C++17