🧠
Brute Force (Check All Teams)
💡 This approach exists to understand the problem's combinatorial nature and why naive enumeration is infeasible, motivating the need for optimization.
Intuition
Try every possible team combination of size up to k, calculate performance, and track the maximum. This brute force method ensures correctness but is too slow for large inputs.
Algorithm
- Generate all subsets of engineers with size ≤ k.
- For each subset, calculate sum of speeds and minimum efficiency.
- Calculate performance = sum_speeds * min_efficiency.
- Track and return the maximum performance found.
💡 The challenge is the exponential number of subsets, which makes this approach impractical but conceptually straightforward.
from itertools import combinations
MOD = 10**9 + 7
def maxPerformance(n, speed, efficiency, k):
max_perf = 0
for team_size in range(1, k+1):
for team in combinations(range(n), team_size):
sum_speed = sum(speed[i] for i in team)
min_eff = min(efficiency[i] for i in team)
perf = sum_speed * min_eff
if perf > max_perf:
max_perf = perf
return max_perf % MOD
# Example usage
if __name__ == '__main__':
n = 6
speed = [2,10,3,1,5,8]
efficiency = [5,4,3,9,7,2]
k = 2
print(maxPerformance(n, speed, efficiency, k))
Line Notes
from itertools import combinationsImport combinations to generate all possible teams
for team_size in range(1, k+1):Iterate over all possible team sizes up to k to cover all team sizes
for team in combinations(range(n), team_size):Generate all subsets of the current team size
sum_speed = sum(speed[i] for i in team)Calculate total speed for the current team
min_eff = min(efficiency[i] for i in team)Find minimum efficiency in the current team, which is the bottleneck
perf = sum_speed * min_effCalculate performance for the current team
if perf > max_perf:Update max performance if current performance is better
return max_perf % MODReturn the maximum performance modulo 10^9+7 as required
import java.util.*;
public class Solution {
static final int MOD = 1000000007;
public static int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
int maxPerf = 0;
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < n; i++) indices.add(i);
for (int teamSize = 1; teamSize <= k; teamSize++) {
List<List<Integer>> combos = combinations(indices, teamSize);
for (List<Integer> team : combos) {
int sumSpeed = 0;
int minEff = Integer.MAX_VALUE;
for (int idx : team) {
sumSpeed += speed[idx];
minEff = Math.min(minEff, efficiency[idx]);
}
int perf = sumSpeed * minEff;
if (perf > maxPerf) maxPerf = perf;
}
}
return maxPerf % MOD;
}
private static List<List<Integer>> combinations(List<Integer> arr, int k) {
List<List<Integer>> res = new ArrayList<>();
backtrack(arr, k, 0, new ArrayList<>(), res);
return res;
}
private static void backtrack(List<Integer> arr, int k, int start, List<Integer> temp, List<List<Integer>> res) {
if (temp.size() == k) {
res.add(new ArrayList<>(temp));
return;
}
for (int i = start; i < arr.size(); i++) {
temp.add(arr.get(i));
backtrack(arr, k, i + 1, temp, res);
temp.remove(temp.size() - 1);
}
}
public static void main(String[] args) {
int n = 6;
int[] speed = {2,10,3,1,5,8};
int[] efficiency = {5,4,3,9,7,2};
int k = 2;
System.out.println(maxPerformance(n, speed, efficiency, k));
}
}
Line Notes
for (int teamSize = 1; teamSize <= k; teamSize++)Iterate over all team sizes up to k to cover all possibilities
List<List<Integer>> combos = combinations(indices, teamSize);Generate all combinations of the current team size
for (int idx : team)Calculate sum of speeds and minimum efficiency for the current team
if (perf > maxPerf) maxPerf = perf;Update max performance if current is better
return maxPerf % MOD;Return the maximum performance modulo 10^9+7 as required
private static List<List<Integer>> combinations(List<Integer> arr, int k)Helper method to generate all combinations of size k
backtrack(...)Backtracking method to build combinations recursively
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MOD = 1e9 + 7;
void backtrack(vector<int>& arr, int k, int start, vector<int>& temp, vector<vector<int>>& res) {
if ((int)temp.size() == k) {
res.push_back(temp);
return;
}
for (int i = start; i < (int)arr.size(); i++) {
temp.push_back(arr[i]);
backtrack(arr, k, i + 1, temp, res);
temp.pop_back();
}
}
vector<vector<int>> combinations(vector<int>& arr, int k) {
vector<vector<int>> res;
vector<int> temp;
backtrack(arr, k, 0, temp, res);
return res;
}
int maxPerformance(int n, vector<int>& speed, vector<int>& efficiency, int k) {
int maxPerf = 0;
vector<int> indices(n);
for (int i = 0; i < n; i++) indices[i] = i;
for (int teamSize = 1; teamSize <= k; teamSize++) {
vector<vector<int>> combos = combinations(indices, teamSize);
for (auto& team : combos) {
int sumSpeed = 0;
int minEff = INT_MAX;
for (int idx : team) {
sumSpeed += speed[idx];
minEff = min(minEff, efficiency[idx]);
}
int perf = sumSpeed * minEff;
if (perf > maxPerf) maxPerf = perf;
}
}
return maxPerf % MOD;
}
int main() {
int n = 6;
vector<int> speed = {2,10,3,1,5,8};
vector<int> efficiency = {5,4,3,9,7,2};
int k = 2;
cout << maxPerformance(n, speed, efficiency, k) << endl;
return 0;
}
Line Notes
for (int teamSize = 1; teamSize <= k; teamSize++)Loop over all team sizes up to k to cover all possibilities
vector<vector<int>> combos = combinations(indices, teamSize);Generate all combinations of the current team size
for (int idx : team)Calculate sum of speeds and minimum efficiency for the current team
if (perf > maxPerf) maxPerf = perf;Update max performance if current is better
return maxPerf % MOD;Return the maximum performance modulo 10^9+7 as required
void backtrack(...)Recursive helper to generate combinations by backtracking
temp.push_back(arr[i])Add current element to the temporary combination
temp.pop_back()Remove last element to backtrack and try other combinations
function* combinations(arr, k, start = 0, combo = []) {
if (combo.length === k) {
yield combo;
return;
}
for (let i = start; i < arr.length; i++) {
yield* combinations(arr, k, i + 1, combo.concat(arr[i]));
}
}
const MOD = 1e9 + 7;
function maxPerformance(n, speed, efficiency, k) {
let maxPerf = 0;
const indices = [...Array(n).keys()];
for (let teamSize = 1; teamSize <= k; teamSize++) {
for (const team of combinations(indices, teamSize)) {
let sumSpeed = 0;
let minEff = Infinity;
for (const idx of team) {
sumSpeed += speed[idx];
minEff = Math.min(minEff, efficiency[idx]);
}
const perf = sumSpeed * minEff;
if (perf > maxPerf) maxPerf = perf;
}
}
return maxPerf % MOD;
}
// Example usage
console.log(maxPerformance(6, [2,10,3,1,5,8], [5,4,3,9,7,2], 2));
Line Notes
function* combinations(arr, k, start = 0, combo = [])Generator function to yield all combinations of size k recursively
if (combo.length === k)Base case: yield the current combination when size k is reached
for (let i = start; i < arr.length; i++)Iterate over remaining elements to build combinations
yield* combinations(arr, k, i + 1, combo.concat(arr[i]))Recursively yield combinations including current element
for (let teamSize = 1; teamSize <= k; teamSize++)Iterate over all team sizes up to k
for (const idx of team)Calculate sum speed and min efficiency for current team
if (perf > maxPerf) maxPerf = perf;Update max performance if current is better
return maxPerf % MOD;Return the maximum performance modulo 10^9+7 as required
TimeO(n choose k * k) which is exponential and infeasible for large n
SpaceO(k) for recursion stack and temporary storage
Enumerating all subsets of size up to k leads to combinatorial explosion, making this approach impractical beyond small inputs.
💡 For n=20 and k=10, this means billions of combinations, which is impossible to compute in reasonable time.
Interview Verdict: TLE
This approach is too slow for large inputs but is useful to understand the problem's brute force baseline.