Geekland is conducting a programming contest that lasts for n minutes.
- The contest contains en number of easy problems and hn number of hard problems.
- Geek will be awarded em and hm marks for solving an easy and hard question respectively.
- Geek takes et minutes to solve an easy problem and ht minutes to solve a hard problem successfully.
Return an array of size 2 containing the number of easy and hard problems Geek should solve to maximize the total score. If multiple solutions yield the same maximum score, choose the one that solves the maximum number of easy questions.
Examples:
Input: n = 180, en = 4, hn = 6, em = 2,
hm = 5, et = 20, ht = 40
Output: [1, 4]
Explanation: Solving 1 easy and 4 hard problems takes 20 + 4 × 40 = 180 minutes. Geek earns 1 × 2 + 4 × 5 = 22 marks, which is the maximum possible score.Input: n = 50, en = 5, hn = 3, em = 5,
hm = 10, et = 10, ht = 20
Output: [5, 0]
Explanation: Solving 1 easy and 2 hard problems or 3 easy and 1 hard problem or 5 easy problems all yield the same maximum score of 25. Since Geek prefer solving more easy problems, he will solve 5 easy problems.
Table of Content
[Naive Approach] Trying All Possible Combination - O(en*hn) Time and O(1) Space
The idea is to iterate over all possible combinations of easy and hard problems that can be solved and select the one that yields the maximum score. If multiple combinations produce the same maximum score, choose the one with the greater number of easy problems.
#include <bits/stdc++.h>
using namespace std;
vector<int> maximumScore(int n, int en, int hn, int em,
int hm, int et, int ht) {
long long maxi = -1;
int easy = 0;
int hard = 0;
// Double loop checking every single combination
for (long long i = 0; i <= en; i++) {
for (long long j = 0; j <= hn; j++) {
long long totTime = i * et + j * ht;
// Only process if it fits within the time limit
if (totTime <= n) {
long long curr = i * em + j * hm;
if (curr > maxi) {
maxi = curr;
easy = i;
hard = j;
}
else if (curr == maxi) {
if (i > easy) {
easy = i;
hard = j;
}
}
}
}
}
return {easy, hard};
}
int main() {
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
vector<int> ans = maximumScore(n, en, hn, em, hm, et, ht);
cout << "[" << ans[0] << ", " << ans[1] << "]\n";
return 0;
}
import java.util.ArrayList;
public class GFG {
public static ArrayList<Integer> maximumScore(int n, int en, int hn, int em,
int hm, int et, int ht) {
long maxi = -1;
int easy = 0;
int hard = 0;
// Double loop checking every single combination
for (long i = 0; i <= en; i++) {
for (long j = 0; j <= hn; j++) {
long totTime = i * et + j * ht;
// Only process if it fits within the time limit
if (totTime <= n) {
long curr = i * em + j * hm;
if (curr > maxi) {
maxi = curr;
easy = (int) i;
hard = (int) j;
}
else if (curr == maxi) {
if (i > easy) {
easy = (int) i;
hard = (int) j;
}
}
}
}
}
ArrayList<Integer> ans = new ArrayList<>();
ans.add(easy);
ans.add(hard);
return ans;
}
public static void main(String[] args) {
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
ArrayList<Integer> ans = maximumScore(n, en, hn, em, hm, et, ht);
System.out.println(ans);
}
}
def maximumScore(n, en, hn, em, hm, et, ht):
maxi = -1
easy = 0
hard = 0
# Double loop checking every single combination
for i in range(en + 1):
for j in range(hn + 1):
totTime = i * et + j * ht
# Only process if it fits within the time limit
if totTime <= n:
curr = i * em + j * hm
if curr > maxi:
maxi = curr
easy = i
hard = j
elif curr == maxi:
if i > easy:
easy = i
hard = j
return [easy, hard]
if __name__ == '__main__':
n = 180
en = 4
hn = 6
em = 2
hm = 5
et = 20
ht = 40
ans = maximumScore(n, en, hn, em, hm, et, ht)
print('[{}, {}]'.format(ans[0], ans[1]))
using System;
using System.Collections.Generic;
public class GFG {
public static List<int> maximumScore(int n, int en, int hn, int em,
int hm, int et, int ht) {
long maxi = -1;
int easy = 0;
int hard = 0;
// Double loop checking every single combination
for (long i = 0; i <= en; i++) {
for (long j = 0; j <= hn; j++) {
long totTime = i * et + j * ht;
// Only process if it fits within the time limit
if (totTime <= n) {
long curr = i * em + j * hm;
if (curr > maxi) {
maxi = curr;
easy = (int)i;
hard = (int)j;
}
else if (curr == maxi) {
if (i > easy) {
easy = (int)i;
hard = (int)j;
}
}
}
}
}
return new List<int> { easy, hard };
}
public static void Main() {
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
List<int> ans = maximumScore(n, en, hn, em, hm, et, ht);
Console.WriteLine("[" + ans[0] + ", " + ans[1] + "]");
}
}
function maximumScore(n, en, hn, em, hm, et, ht) {
let maxi = -1;
let easy = 0;
let hard = 0;
// Double loop checking every single combination
for (let i = 0; i <= en; i++) {
for (let j = 0; j <= hn; j++) {
let totTime = i * et + j * ht;
// Only process if it fits within the time limit
if (totTime <= n) {
let curr = i * em + j * hm;
if (curr > maxi) {
maxi = curr;
easy = i;
hard = j;
}
else if (curr === maxi) {
if (i > easy) {
easy = i;
hard = j;
}
}
}
}
}
return [easy, hard];
}
// Driver code
const n = 180;
const en = 4;
const hn = 6;
const em = 2;
const hm = 5;
const et = 20;
const ht = 40;
const ans = maximumScore(n, en, hn, em, hm, et, ht);
console.log(`[${ans[0]}, ${ans[1]}]`);
Output
[1, 4]
[Expected Approach] Iterating Over Hard Problems- O(hn) Time and O(1) Space
The idea is to iterate over every possible number of hard problems and compute the maximum number of easy problems that can be solved with the remaining time. Then, calculate the total score for each combination and keep the one with the highest score.
- Iterate over all possible numbers of hard problems, since the number of easy problems can be much larger.
- For each choice, check if the required time is within the given limit.
- Compute the remaining time and calculate the maximum number of easy problems that can be solved, without exceeding the available easy problems.
- Calculate the total score for this combination.
- If the score is greater than the maximum score so far, update the answer.
- If the score is equal to the maximum score, choose the combination with more easy problems.
- Use long long for calculations to avoid integer overflow.
Dry Run for n = 180, en = 4, hn = 6, em = 2, hm = 5, et = 20, ht = 40
- Initialize maxi = -1, easy = 0, hard = 0.
- j = 0: hardTime = 0, remTime = 180, i = 4, curr = 8. Update answer to (4, 0), maxi = 8.
- j = 1: hardTime = 40, remTime = 140, i = 4, curr = 13. Update answer to (4, 1), maxi = 13.
- j = 2: hardTime = 80, remTime = 100, i = 4, curr = 18. Update answer to (4, 2), maxi = 18.
- j = 3: hardTime = 120, remTime = 60, i = 3, curr = 21. Update answer to (3, 3), maxi = 21.
- j = 4: hardTime = 160, remTime = 20, i = 1, curr = 22. Update answer to (1, 4), maxi = 22.
- j = 5: hardTime = 200 > 180, so break the loop since further values of j will also exceed the time limit.
Return [1, 4].
#include <bits/stdc++.h>
using namespace std;
vector<int> maximumScore(int n, int en, int hn, int em,
int hm, int et, int ht) {
long long maxi = -1;
int easy = 0;
int hard = 0;
// Iterate only over the possible number of hard problems
for (long long j = 0; j <= hn; j++) {
long long hardTime = j * ht;
// If the hard problems take more time than total time, break early
if (hardTime > n) {
break;
}
long long remTime = n - hardTime;
// Calculate max easy problems we can solve with remaining time
int maxEasy = remTime / et;
// We can't solve more easy problems than what's available
long long i = min(en, maxEasy);
long long curr = i * em + j * hm;
// Update maxi and problem counts
if (curr > maxi) {
maxi = curr;
easy = i;
hard = j;
}
// Handle the tie-breaking condition:
// choose the one with more easy problems
else if (curr == maxi) {
if (i > easy) {
easy = i;
hard = j;
}
}
}
return {easy, hard};
}
int main() {
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
vector<int> ans = maximumScore(n, en, hn, em, hm, et, ht);
cout << "[" << ans[0] << ", " << ans[1] << "]\n";
return 0;
}
import java.util.ArrayList;
public class GFG {
public static ArrayList<Integer> maximumScore(int n, int en, int hn,
int em, int hm, int et, int ht) {
long maxi = -1;
int easy = 0;
int hard = 0;
// Iterate only over the possible number of hard problems
for (long j = 0; j <= hn; j++) {
long hardTime = j * ht;
// If the hard problems take more time than total time, break early
if (hardTime > n) {
break;
}
long remTime = n - hardTime;
// Calculate max easy problems we can solve with remaining time
int maxEasy = (int) (remTime / et);
// We can't solve more easy problems than what's available
long i = Math.min(en, maxEasy);
long curr = i * em + j * hm;
// Update maxi and problem counts
if (curr > maxi) {
maxi = curr;
easy = (int) i;
hard = (int) j;
}
// Handle the tie-breaking condition:
// choose the one with more easy problems
else if (curr == maxi) {
if (i > easy) {
easy = (int) i;
hard = (int) j;
}
}
}
ArrayList<Integer> ans = new ArrayList<>();
ans.add(easy);
ans.add(hard);
return ans;
}
public static void main(String[] args) {
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
ArrayList<Integer> ans = maximumScore(n, en, hn, em, hm, et, ht);
System.out.println(ans);
}
}
def maximumScore(n, en, hn, em, hm, et, ht):
maxi = -1
easy = 0
hard = 0
# Iterate only over the possible number of hard problems
for j in range(hn + 1):
hardTime = j * ht
# If the hard problems take more time than total time, break early
if hardTime > n:
break
remTime = n - hardTime
# Calculate max easy problems we can solve with remaining time
maxEasy = remTime // et
# We can't solve more easy problems than what's available
i = min(en, maxEasy)
curr = i * em + j * hm
# Update maxi and problem counts
if curr > maxi:
maxi = curr
easy = i
hard = j
# Handle the tie-breaking condition:
# choose the one with more easy problems
elif curr == maxi:
if i > easy:
easy = i
hard = j
return [easy, hard]
if __name__ == '__main__':
n = 180
en = 4
hn = 6
em = 2
hm = 5
et = 20
ht = 40
ans = maximumScore(n, en, hn, em, hm, et, ht)
print(ans)
using System;
using System.Collections.Generic;
public class GFG
{
public static List<int> maximumScore(int n, int en, int hn, int em,
int hm, int et, int ht) {
long maxi = -1;
int easy = 0;
int hard = 0;
// Iterate only over the possible number of hard problems
for (long j = 0; j <= hn; j++)
{
long hardTime = j * ht;
// If the hard problems take more time than total time, break early
if (hardTime > n)
{
break;
}
long remTime = n - hardTime;
// Calculate max easy problems we can solve with remaining time
int maxEasy = (int)(remTime / et);
// We can't solve more easy problems than what's available
long i = Math.Min(en, maxEasy);
long curr = i * em + j * hm;
// Update maxi and problem counts
if (curr > maxi)
{
maxi = curr;
easy = (int)i;
hard = (int)j;
}
// Handle the tie-breaking condition:
// choose the one with more easy problems
else if (curr == maxi)
{
if (i > easy)
{
easy = (int)i;
hard = (int)j;
}
}
}
return new List<int> { easy, hard };
}
public static void Main()
{
int n = 180;
int en = 4;
int hn = 6;
int em = 2;
int hm = 5;
int et = 20;
int ht = 40;
List<int> ans = maximumScore(n, en, hn, em, hm, et, ht);
Console.WriteLine("[" + string.Join(", ", ans) + "]");
}
}
function maximumScore(n, en, hn, em, hm, et, ht) {
let maxi = -1;
let easy = 0;
let hard = 0;
// Iterate only over the possible number of hard problems
for (let j = 0; j <= hn; j++) {
let hardTime = j * ht;
// If the hard problems take more time than total time, break early
if (hardTime > n) {
break;
}
let remTime = n - hardTime;
// Calculate max easy problems we can solve with remaining time
let maxEasy = Math.floor(remTime / et);
// We can't solve more easy problems than what's available
let i = Math.min(en, maxEasy);
let curr = i * em + j * hm;
// Update maxi and problem counts
if (curr > maxi) {
maxi = curr;
easy = i;
hard = j;
}
// Handle the tie-breaking condition:
// choose the one with more easy problems
else if (curr === maxi) {
if (i > easy) {
easy = i;
hard = j;
}
}
}
return [easy, hard];
}
// Driver code
const n = 180;
const en = 4;
const hn = 6;
const em = 2;
const hm = 5;
const et = 20;
const ht = 40;
const ans = maximumScore(n, en, hn, em, hm, et, ht);
console.log(`[${ans.join(", ")}]`);
Output
[1, 4]