[
dp
dfs
]
Leetcode 0879 Profitable Schemes
Problem statement
https://leetcode.com/problems/profitable-schemes/
Solution
Question we need to answer here is the following: given numbers $[p_0, \dots, p_{n-1}]$ and $[g_0, \dots g_{n-1}]$ how many subsets there are, such that: \(p_{i_1} + \dots + p_{i_k} \geqslant P, \ \ \ g_{i_1} + \dots g_{i_k} \leqslant G.\) The problem if we write is like this, is that first sum is not bounded from above, so let us solve two different problems:
- $p_{i_1} + \dots + p_{i_k} \leqslant P - 1, \ \ \ g_{i_1} + \dots g_{i_k} \leqslant G$, for which we will use
dfs1(i, j, l)
function. Herei
is current profit we have,j
is how many people we used andl
is number of crime we are working with. Functiondfs1(P - 1, G, n - 1)
will answer a question: how many solutions we have. - $g_{i_1} + \dots g_{i_k} \leqslant G$, for which we will use
dfs2(j, l)
function. Similar to previous function, here we have only two states:j
is how many people we used andl
is number of crime we are working with.
Complexity
Time complexity is O(nPG)
, space as well.
Code 1
class Solution:
def profitableSchemes(self, G, P, group, profit):
n, MOD = len(group), 10**9 + 7
@lru_cache(None)
def dfs1(i, j, l):
if l == -1: return 1
ans = dfs1(i, j, l - 1)
if i - profit[l] >= 0 and j - group[l] >= 0:
ans += dfs1(i - profit[l], j - group[l], l - 1)
return ans % MOD
@lru_cache(None)
def dfs2(j, l):
if l == -1: return 1
ans = dfs2(j, l - 1)
if j - group[l] >= 0:
ans += dfs2(j - group[l], l - 1)
return ans % MOD
return (dfs2(G, n - 1) - dfs1(P - 1, G, n - 1)) % MOD
Code 2
Actually, it can be written in shorter way, with the same complexity.
class Solution:
def profitableSchemes(self, G, P, group, profit):
n, MOD = len(group), 10**9 + 7
@lru_cache(None)
def dfs(i, j, l):
if l == -1: return i == 0
ans = dfs(i, j, l - 1)
if j - group[l] >= 0:
ans += dfs(max(0, i - profit[l]), j - group[l], l - 1)
return ans % MOD
return dfs(P, G, n - 1)