discontinuous's blog

By discontinuous, history, 5 hours ago, In English

I tried solving this problem of CSES Problemset: Coin Combinations II

This is the solution I came up with using Recursive DP :-

#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
#define pb push_back

const ll MOD = 1e9 + 7;
int n, k, a, b, c, d, x, y;

vector<int> arr(101);
vector<vector<int>> dp(1000001, vector<int>(101, -1));

int ways(int target, int index) {
	if(target == 0) return 1;
	if(index == n || target < 0) return 0;

	if(dp[target][index] != -1) {
		// cout << target << ' ' << index << "\n";
		return dp[target][index];
	}
	else dp[target][index] = ((ways(target - arr[index], index))%MOD + (ways(target, index+1))%MOD)%MOD;

	return dp[target][index];
}

int main() {
    ios::sync_with_stdio(false);
    cout.tie(0); cin.tie(0);
 
	cin >> n >> k;
	for(int j = 0; j<n; j++) cin >> arr[j];

	cout << ways(k, 0);
 
	return 0;
}

Most of the tutorials used Iterative DP for the solution but I am not able to see why this recursive DP solution won't work. This solution gives TLE on 7/15 test cases.

Can someone please help me with this

  • Vote: I like it
  • 0
  • Vote: I do not like it

»
4 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

you are declaring global DP table which is of the size 100 million which takes time, and second thing If one of your coin denominations is very small (like 1), the recursion may go very deep (up to 1e6 levels in the worst case), which is inefficient compared to an iterative approach.

  • »
    »
    4 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    So there's no way to make it work with recursive DP?

    • »
      »
      »
      76 minutes ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      May be No!

  • »
    »
    5 minutes ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    try using arrays instead of vectors