Skip to content

Commit e262a3d

Browse files
authored
Merge pull request apachecn#56 from yudaer/master
Create 879._Profitable_Schemes.md
2 parents 4f8bf37 + a1c5a06 commit e262a3d

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
### 879. Profitable Schemes
2+
3+
4+
5+
题目:
6+
https://leetcode.com/problems/profitable-schemes/
7+
8+
难度:
9+
Hard
10+
11+
题意:
12+
13+
1. 给定一个集合,每个集合都有一个group和profile,给定两个数G和P
14+
2. 求在集合所有的子集合中,group和不大于G,并且profile和不小于P的子集合个数
15+
16+
思路:
17+
18+
- 这是一个01背包模型的变种
19+
- 大家思考一下,01背包是说,给定一个集合,每个集合有一个成本和一个收益,求成本和不大于总成本的最大收益
20+
- 这个题有两个条件,因此有两个规划方向。这两个方向还不一样,group是约束条件,规划长度是1-G,而profile是下限,规划长度也是1-P(因为超过P再记录P的具体的值已经没有意义了,所以一切>=P都可用P代替)
21+
- 最后的结果就是总group在1-G中,并且总profile>=p的子集合个数
22+
- 复杂度是o(NGP),看数据范围,是不是正好在10^6的量级里面?
23+
24+
代码:
25+
26+
```java
27+
class Solution {
28+
private static int MOD = 1000000007;
29+
30+
public int profitableSchemes(int G, int P, int[] group, int[] profit) {
31+
int[][] dp = new int[G + 1][P + 1];
32+
for(int i = 0;i <= G;i++) {
33+
for (int j = 0;j <= P;j++) {
34+
dp[i][j] = 0;
35+
}
36+
}
37+
dp[0][0] = 1;
38+
for (int k = 0;k < group.length;k++) {
39+
for (int i = G;i >= 0;i--) {
40+
if (i + group[k] > G) {
41+
continue;
42+
}
43+
for (int j = 0;j <= P;j++) {
44+
int p = j + profit[k];
45+
if (p > P) {
46+
p = P;
47+
}
48+
dp[i + group[k]][p] += dp[i][j];
49+
if (dp[i + group[k]][p] >= MOD) {
50+
dp[i + group[k]][p] -= MOD;
51+
}
52+
}
53+
}
54+
}
55+
int ret = 0;
56+
for (int i = 1;i <= G;i++) {
57+
ret += dp[i][P];
58+
if (ret >= MOD) {
59+
ret -= MOD;
60+
}
61+
}
62+
return ret;
63+
}
64+
}
65+
```
66+

0 commit comments

Comments
 (0)