Maximum power in N levels from K such that defeating boss at level A[i] increases power by B[i]
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(); |
29
Time Complexity: O(N log(N))
Auxiliary Space: O(N)
Please Login to comment...