题目描述
H公司在做项目规划,当前3个团队(前端、后端、测试)共同规划完成M个项目,这时候给你3个团队各自人力总和值(XXX人月)。对于某个项目,项目都需要多个团队共同投入完成,每个项目会有一个预估的价值(XXX万元),同时一个项目都需要多个团队共同投入完成(每个项目会有对三个团队的人力需求数量)。让你在多个项目中做项目规划,在人力允许的范围内,使得能够承接的所有项目的预估价值总和量大。
备注:返回结果为能够承接的最大预估价值。如果人力无法承接任何项目,返回0。
输入描述
项目个数:m (0 < n <= 20);
三个团队人力总和:S1,S2,S3 (0 < Si <= 1000)
每个项目预估价值:V1,V2,V3,… Vn;(0 < Vi <= 1000000)
每个项目所需人力:{P11,P12,P13},{P21,P22,P23},{P31,P32,P33},…,{Pm1, Pm2,Pm3}
输出描述
输出项目规划的结果
示例一
输入:
2
100 100 100
10000 8000
60 60 60
60 60 60
输出:
10000
示例二
输入:
3
200 200 200
10000 8000 7000
150 150 150
80 80 80
90 90 90
输出:
15000
说明:
3:3个项目
200 200 200:三个团队各自的人力总和
10000 8000 7000:项目的预估价值(1个项目一个输入,多个项目会有多个输入)
150 150 150:第一个项目对于三个团队的人力需求
80 80 80:第二个项目对于三个团队的人力需求
90 90 90:第三个项目对于三个团队的人力需求
15000:可以容纳8000与7000的项目。
示例三
输入:
3
200 200 200
10000 8000 7000
300 100 100
100 300 100
100 100 300
输出:
0
说明:
3:3个项目
200 200 200:三个团队各自的人力总和
10000 8000 7000:项目的预估价值(1个项目一个输入,多个项目会有多个输入)
300 100 100:第一个项目对于三个团队的人力需求
100 300 100:第二个项目对于三个团队的人力需求
100 100 300∶第三个项目对于三个团队的人力需求
0:无法满足任何一个项目的人力需求
思路
首先可以采用暴力回溯的方法,直接满足条件的减去相对应的值,再进行回溯。
也可以采用01背包的分析方法,每个项目都有选与不选2种状态,共2^20=1048576种可能,枚举每种可能。这个容量有三个维度。但直接写背包会超内存,得提取背包容量和重量的后面多少个0开辟小一点的背包数组才能过。可以采用状态压缩的方法,例如100101表示选中第1、3、6个项目。对于一种情况,可以以O(1)时间复杂度求三个部门的剩余人力和项目的总价值,只要剩余人力不为0即可。
考点
01背包,DFS
Java代码
import java.util.Scanner;
public class Main {
public static int res = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] team = new int[3];
for (int i = 0; i < 3; i++) {
team[i] = in.nextInt();
}
int[] value = new int[3];
for (int i = 0; i < 3; i++) {
value[i] = in.nextInt();
}
int[][] person = new int[n][3];
for (int i = 0; i < n; i++) {
person[i][0] = in.nextInt();
person[i][1] = in.nextInt();
person[i][2] = in.nextInt();
}
dfs(person, team, value, 0, 0);
System.out.println(res);
}
public static void dfs(int[][] person, int[] team, int[] value, int index, int cur){
int n = person.length;
if (index == n) { // 终止条件
res = Math.max(res, cur);
return;
}
for (int i = index; i < n; i++) {
if (team[0] >= person[i][0] && team[1] >= person[i][1] && team[2] >= person[i][2]) {
cur += value[i];
team[0] -= person[i][0];
team[1] -= person[i][1];
team[2] -= person[i][2];
dfs(person, team, value, i + 1, cur);
cur -= value[i];
team[0] += person[i][0];
team[1] += person[i][1];
team[2] += person[i][2];
} else {
dfs(person, team, value, i + 1, cur);
}
}
}
}
留言