Open In App

Maximum power in N levels from K such that defeating boss at level A[i] increases power by B[i]

Last Updated : 24 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays a[] and b[] of size N and an integer K. The task is to find the maximum power that can be achieved in N levels with initial power K such that after defeating the ith level boss of strength a[i], power is increased by b[i]. In order to defeat a boss the power should be greater than or equal to his power.

Examples:

Input: N = 3, K = 10, a[] = {20, 30, 10}, b[] = {9, 100, 10}  
Output: 29
Explanation: First defeat boss at index 3, the power becomes 20, then defeat boss at index 1 and the power becomes 29. Now you can’t defeat any other boss, so 29 is the maximum power you can achieve.
 

Input: N = 2, K = 5, a[] = {7, 10}, b[] = {100, 20}  
Output: 5

 

Approach: The task can be solved using the greedy approach. Find the weakest boss and check if your power is greater than or equal to his power. If yes, then defeat the boss and take the magic box i which will increase your power by b[i]. Keep on repeating this step until there is no magic box left to take or you can’t defeat the weakest boss. Follow the below steps to solve the problem:

  • Finding the weakest boss can be done easily using a minimum priority queue. Note that we will store the values in the priority queue in pairs i.e. {a[i], b[i]} so that the weakest boss is always on top in the priority queue. 

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum power you can achieve.
int maxPower(int a[], int b[], int n, int k)
{
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    for (int i = 0; i < n; i++)
        pq.push({ a[i], b[i] });
 
    int cur_power = k;
 
    while (!pq.empty()) {
        int guard_power = pq.top().first;
        int extra_power = pq.top().second;
        pq.pop();
 
        // The weakest guard has more power than you.
        if (guard_power > cur_power)
            break;
 
        // Defeat the current guard
        // and add extra power
        // to your current power.
        cur_power += extra_power;
    }
 
    return cur_power;
}
 
// Driver function
int main()
{
    int a[] = { 20, 30, 10 };
    int b[] = { 9, 100, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 10;
 
    // Function Call
    cout << maxPower(a, b, n, k);
    return 0;
}


Java




import java.util.*;
 
class GFG {
    // Function to find the maximum power you can achieve.
    static int maxPower(int[] a, int[] b, int n, int k) {
        PriorityQueue<int[]> pq = new PriorityQueue<>((a1, b1) -> Integer.compare(a1[0], b1[0]));
        for (int i = 0; i < n; i++) {
            pq.offer(new int[] { a[i], b[i] });
        }
 
        int curPower = k;
        while (!pq.isEmpty()) {
            int guardPower = pq.peek()[0];
            int extraPower = pq.peek()[1];
            pq.poll();
            // The weakest guard has more power than you.
            if (guardPower > curPower) {
                break;
            }
            // Defeat the current guard
            // and add extra power
            // to your current power.
            curPower += extraPower;
        }
 
        return curPower;
    }
 
    public static void main(String[] args) {
        int[] a = { 20, 30, 10 };
        int[] b = { 9, 100, 10 };
        int n = a.length;
        int k = 10;
        // Function Call
        System.out.println(maxPower(a, b, n, k));
    }
}


Python3




# python program for the above approach
from queue import PriorityQueue
 
# Function to find the maximum power you can achieve.
def maxPower(a, b, n, k):
 
    pq = PriorityQueue()
 
    for i in range(0, n):
        pq.put([a[i], b[i]])
 
    cur_power = k
 
    while (not pq.empty()):
        pw = pq.get()
        guard_power = pw[0]
        extra_power = pw[1]
 
        # The weakest guard has more power than you.
        if (guard_power > cur_power):
            break
 
            # Defeat the current guard
            # and add extra power
            # to your current power.
        cur_power += extra_power
 
    return cur_power
 
# Driver function
if __name__ == "__main__":
 
    a = [20, 30, 10]
    b = [9, 100, 10]
    n = len(a)
    k = 10
 
    # Function Call
    print(maxPower(a, b, n, k))
 
    # This code is contributed by rakeshsahni


C#




// C# program to find the maximum power you can achieve.
 
using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find the maximum power you can achieve.
    static int maxPower(int[] a, int[] b, int n, int k) {
        SortedList<int, int> sortedList = new SortedList<int, int>();
        for (int i = 0; i < n; i++) {
            sortedList.Add(a[i], b[i]);
        }
 
        int curPower = k;
        foreach (KeyValuePair<int, int> guard in sortedList) {
            int guardPower = guard.Key;
            int extraPower = guard.Value;
            // The weakest guard has more power than you.
            if (guardPower > curPower) {
                break;
            }
            // Defeat the current guard
            // and add extra power
            // to your current power.
            curPower += extraPower;
        }
     
        return curPower;
    }
     
    public static void Main() {
        int[] a = { 20, 30, 10 };
        int[] b = { 9, 100, 10 };
        int n = a.Length;
        int k = 10;
        // Function Call
        Console.WriteLine(maxPower(a, b, n, k));
    }
}
 
// This code is contributed by phasing17


Javascript




// JavaScript program to find the maximum power you can achieve.
 
// Function to find the maximum power you can achieve.
function maxPower(a, b, n, k) {
  const pq = new PriorityQueue((a, b) => a[0] - b[0]);
  for (let i = 0; i < n; i++) {
    pq.enqueue([a[i], b[i]]);
  }
 
  let curPower = k;
 
  while (!pq.isEmpty()) {
    const [guardPower, extraPower] = pq.dequeue();
 
    // The weakest guard has more power than you.
    if (guardPower > curPower) {
      break;
    }
 
    // Defeat the current guard and add extra power
    // to your current power.
    curPower += extraPower;
  }
 
  return curPower;
}
 
// PriorityQueue implementation
class PriorityQueue {
  constructor(compare) {
    this.heap = [];
    this.compare = compare;
  }
     
  // push item in priority queue
  enqueue(item) {
    this.heap.push(item);
    this._shiftUp();
  }
     
  // pop item from top of the priority queue and return that item
  dequeue() {
    if (this.isEmpty()) {
      throw new Error("Priority queue is empty");
    }
 
    const first = 0;
    const last = this.heap.length - 1;
    this._swap(first, last);
    const item = this.heap.pop();
    this._shiftDown();
    return item;
  }
     
  // if priority queue is empty or not
  isEmpty() {
    return this.heap.length === 0;
  }
     
  // to get parent index in the array
  _getParentIndex(childIndex) {
    return Math.floor((childIndex - 1) / 2);
  }
 
  // to get left child index in the array
  _getLeftChildIndex(parentIndex) {
    return parentIndex * 2 + 1;
  }
 
  // to get right child index in the array
  _getRightChildIndex(parentIndex) {
    return parentIndex * 2 + 2;
  }
 
  // check if parent exists
  _hasParent(childIndex) {
    return this._getParentIndex(childIndex) >= 0;
  }
 
  // check if left child exists
  _hasLeftChild(parentIndex) {
    return this._getLeftChildIndex(parentIndex) < this.heap.length;
  }
 
  // check if right child exists
  _hasRightChild(parentIndex) {
    return this._getRightChildIndex(parentIndex) < this.heap.length;
  }
 
  // access parent
  _getParent(childIndex) {
    return this.heap[this._getParentIndex(childIndex)];
  }
 
  // access left child
  _getLeftChild(parentIndex) {
    return this.heap[this._getLeftChildIndex(parentIndex)];
  }
 
  // access right child
  _getRightChild(parentIndex) {
    return this.heap[this._getRightChildIndex(parentIndex)];
  }
 
  // swap numbers
  _swap(index1, index2) {
    [this.heap[index1], this.heap[index2]] = [
      this.heap[index2],
      this.heap[index1],
    ];
  }
     
  // heapify up once pushed new element
  _shiftUp() {
    let index = this.heap.length - 1;
    while (
      this._hasParent(index) &&
      this.compare(this.heap[index], this._getParent(index)) < 0
    ) {
      const parentIndex = this._getParentIndex(index);
      this._swap(index, parentIndex);
      index = parentIndex;
    }
  }
 
  // heapify down once popped element
  _shiftDown() {
    let index = 0;
    while (this._hasLeftChild(index)) {
      let smallerChildIndex = this._getLeftChildIndex(index);
      if (
        this._hasRightChild(index) &&
        this.compare(this._getRightChild(index), this._getLeftChild(index)) < 0
      ) {
        smallerChildIndex = this._getRightChildIndex(index);
      }
 
      if (
        this.compare(this.heap[index], this.heap[smallerChildIndex]) < 0
      ) {
        break;
      } else {
        this._swap(index, smallerChildIndex);
      }
 
      index = smallerChildIndex;
    }
  }
}
 
// Driver code
function main() {
  const a = [20, 30, 10];
  const b = [9, 100, 10];
  const n = a.length;
  const k = 10;
  const maxPoweR = maxPower(a, b, n, k);
  console.log(maxPoweR);
}
 
// main function call
main();


Output

29

Time Complexity: O(N log(N))
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads