879. 盈利计划

集团里有 n 名员工,他们可以完成各种各样的工作创造利润。
i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与。如果成员参与了其中一项工作,就不能参与另一项工作。
工作的任何至少产生 minProfit 利润的子集称为 盈利计划 。并且工作的成员总数最多为 n

输入:n = 5, minProfit = 3, group = [2,2], profit = [2,3]
输出:2
解释:至少产生 3 的利润,该集团可以完成工作 0 和工作 1 ,或仅完成工作 1 。
总的来说,有两种计划。

  1. //三维dp ,时空lmn
  2. func profitableSchemes(n, minProfit int, group, profit []int) (sum int) {
  3. const mod int = 1e9 + 7
  4. ng := len(group)
  5. dp := make([][][]int, ng+1)
  6. for i := range dp {
  7. dp[i] = make([][]int, n+1)
  8. for j := range dp[i] {
  9. dp[i][j] = make([]int, minProfit+1)
  10. }
  11. }
  12. dp[0][0][0] = 1
  13. for i, members := range group {
  14. earn := profit[i]
  15. for j := 0; j <= n; j++ {
  16. for k := 0; k <= minProfit; k++ {
  17. if j < members {
  18. dp[i+1][j][k] = dp[i][j][k]
  19. } else {
  20. dp[i+1][j][k] = (dp[i][j][k] + dp[i][j-members][max(0, k-earn)]) % mod
  21. }
  22. }
  23. }
  24. }
  25. for _, d := range dp[ng] {
  26. sum = (sum + d[minProfit]) % mod
  27. }
  28. return
  29. }
  30. func max(a, b int) int {
  31. if a > b {
  32. return a
  33. }
  34. return b
  35. }
  1. //二维dp
  2. func profitableSchemes(n, minProfit int, group, profit []int) (sum int) {
  3. const mod int = 1e9 + 7
  4. dp := make([][]int, n+1)
  5. for i := range dp {
  6. dp[i] = make([]int, minProfit+1)
  7. dp[i][0] = 1
  8. }
  9. for i, members := range group {
  10. earn := profit[i]
  11. for j := n; j >= members; j-- {
  12. for k := minProfit; k >= 0; k-- {
  13. dp[j][k] = (dp[j][k] + dp[j-members][max(0, k-earn)]) % mod
  14. }
  15. }
  16. }
  17. return dp[n][minProfit]
  18. }
  19. func max(a, b int) int {
  20. if a > b {
  21. return a
  22. }
  23. return b
  24. }