Minimize prize count required such that smaller value gets less prize in an adjacent pair
Last Updated :
09 Nov, 2023
Given an array arr[] of length N, the task is to find the minimum number of prizes required such that if two elements are adjacent, then elements with smaller value gets a less number of prizes compared to its adjacent elements with greater value.
Note: Each elements will get at least one prize.
Examples:
Input: arr[] = {1, 2, 2, 3}
Output: 6
Explanation:
Element at index {0} will get {1} prize.
Element at index {1} will get {2} prizes.
Element at index {2} will get {1} prizes.
Element at index {3} will get {2} prizes.
So, the total number of prizes required to satisfy
the above conditions are 6
Input: arr[] = {3, 2, 2, 1}
Output: 6
Explanation:
Element at index {0} will get {2} prize.
Element at index {1} will get {1} prizes.
Element at index {2} will get {2} prizes.
Element at index {3} will get {1} prizes.
So, the total number of prizes required to satisfy
the above conditions are 6
Naive Approach: Traverse over the elements of the array and for each element of the array find the consecutive smaller elements at the left of the element and find the consecutive smaller elements on the right of that index.
Prize at index i = max(Consecutive smaller elements at left, Consecutive smaller elements at right, 1)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findMinPrizes( int arr[], int n)
{
int totalPrizes = 0, j, x, y;
for ( int i = 0; i < n; i++) {
x = 1;
j = i;
while (j > 0 && arr[j] > arr[j - 1]) {
x++;
j--;
}
j = i;
y = 1;
while (j < n - 1 && arr[j] > arr[j + 1]) {
y++;
j++;
}
totalPrizes += max({ x, y });
}
cout << totalPrizes << endl;
return 0;
}
int main()
{
int arr[] = { 1, 2, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
findMinPrizes(arr, n);
}
|
Java
import java.util.*;
class GFG{
static int findMinPrizes( int arr[], int n)
{
int totalPrizes = 0 , j, x, y;
for ( int i = 0 ; i < n; i++)
{
x = 1 ;
j = i;
while (j > 0 && arr[j] > arr[j - 1 ])
{
x++;
j--;
}
j = i;
y = 1 ;
while (j < n - 1 && arr[j] > arr[j + 1 ])
{
y++;
j++;
}
totalPrizes += Math.max(x, y );
}
System.out.print(totalPrizes + "\n" );
return 0 ;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 2 , 3 };
int n = arr.length;
findMinPrizes(arr, n);
}
}
|
Python3
def findMinPrizes(arr, n):
totalPrizes = 0
for i in range (n):
x = 1
j = i
while (j > 0 and arr[j] > arr[j - 1 ]):
x + = 1
j - = 1
j = i
y = 1
while (j < n - 1 and arr[j] >
arr[j + 1 ]):
y + = 1
j + = 1
totalPrizes + = max (x, y)
print (totalPrizes)
arr = [ 1 , 2 , 2 , 3 ]
n = len (arr)
findMinPrizes(arr, n)
|
C#
using System;
class GFG{
static int findMinPrizes( int []arr, int n)
{
int totalPrizes = 0, j, x, y;
for ( int i = 0; i < n; i++)
{
x = 1;
j = i;
while (j > 0 && arr[j] > arr[j - 1])
{
x++;
j--;
}
j = i;
y = 1;
while (j < n - 1 &&
arr[j] > arr[j + 1])
{
y++;
j++;
}
totalPrizes += Math.Max(x, y);
}
Console.Write(totalPrizes + "\n" );
return 0;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 2, 3 };
int n = arr.Length;
findMinPrizes(arr, n);
}
}
|
Javascript
<script>
function findMinPrizes(arr, n)
{
let totalPrizes = 0, j, x, y;
for (let i = 0; i < n; i++) {
x = 1;
j = i;
while (j > 0 && arr[j] > arr[j - 1]) {
x++;
j--;
}
j = i;
y = 1;
while (j < n - 1 && arr[j] > arr[j + 1]) {
y++;
j++;
}
totalPrizes += Math.max( x, y );
}
document.write(totalPrizes);
return 0;
}
let arr = [ 1, 2, 2, 3 ];
let n = arr.length;
findMinPrizes(arr, n);
</script>
|
Performance Analysis:
- Time Complexity: O(N2)
- Auxiliary Space: O(1)
Efficient Approach: The idea is to precompute the count of consecutive smaller elements at left and right for every element of the array. It means that, if an element on the left is smaller, then all the smaller elements at the left of that element will also be smaller to the current element. i.e.
if (arr[i-1] < arr[i])
smallerLeft[i] = smallerLeft[i-1] + 1
Similarly, the consecutive smaller elements can be computed using the fact that, if an element on the right is greater than the current element then the consecutive greater elements on the right will also be greater than the current element. i.e.
if (arr[i] < arr[i+1])
smallerRight[i] = smallerRight[i+1] + 1
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minPrizes( int arr[], int n)
{
int dpLeft[n];
dpLeft[0] = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
dpLeft[i] = dpLeft[i - 1] + 1;
}
else {
dpLeft[i] = 1;
}
}
int dpRight[n];
dpRight[n - 1] = 1;
for ( int i = n - 2; i >= 0; i--) {
if (arr[i] > arr[i + 1]) {
dpRight[i] = dpRight[i + 1] + 1;
}
else {
dpRight[i] = 1;
}
}
int totalPrizes = 0;
for ( int i = 0; i < n; i++) {
totalPrizes += max(dpLeft[i],
dpRight[i]);
}
cout << totalPrizes << endl;
return 0;
}
int main()
{
int arr[] = { 1, 2, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
minPrizes(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int minPrizes( int arr[], int n)
{
int []dpLeft = new int [n];
dpLeft[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++)
{
if (arr[i] > arr[i - 1 ])
{
dpLeft[i] = dpLeft[i - 1 ] + 1 ;
}
else
{
dpLeft[i] = 1 ;
}
}
int []dpRight = new int [n];
dpRight[n - 1 ] = 1 ;
for ( int i = n - 2 ; i >= 0 ; i--)
{
if (arr[i] > arr[i + 1 ])
{
dpRight[i] = dpRight[i + 1 ] + 1 ;
}
else
{
dpRight[i] = 1 ;
}
}
int totalPrizes = 0 ;
for ( int i = 0 ; i < n; i++)
{
totalPrizes += Math.max(dpLeft[i],
dpRight[i]);
}
System.out.print(totalPrizes + "\n" );
return 0 ;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 2 , 3 };
int n = arr.length;
minPrizes(arr, n);
}
}
|
Python3
def minPrizes(arr, n):
dpLeft = [ 0 ] * n
dpLeft[ 0 ] = 1
for i in range (n):
if arr[i] > arr[i - 1 ]:
dpLeft[i] = dpLeft[i - 1 ] + 1
else :
dpLeft[i] = 1
dpRight = [ 0 ] * n
dpRight[ - 1 ] = 1
for i in range (n - 2 , - 1 , - 1 ):
if arr[i] > arr[i + 1 ]:
dpRight[i] = dpRight[i + 1 ] + 1
else :
dpRight[i] = 1
totalPrizes = 0
for i in range (n):
totalPrizes + = max (dpLeft[i],
dpRight[i])
print (totalPrizes)
arr = [ 1 , 2 , 2 , 3 ]
n = len (arr)
minPrizes(arr, n)
|
C#
using System;
class GFG{
static int minPrizes( int []arr, int n)
{
int []dpLeft = new int [n];
dpLeft[0] = 1;
for ( int i = 1; i < n; i++)
{
if (arr[i] > arr[i - 1])
{
dpLeft[i] = dpLeft[i - 1] + 1;
}
else
{
dpLeft[i] = 1;
}
}
int []dpRight = new int [n];
dpRight[n - 1] = 1;
for ( int i = n - 2; i >= 0; i--)
{
if (arr[i] > arr[i + 1])
{
dpRight[i] = dpRight[i + 1] + 1;
}
else
{
dpRight[i] = 1;
}
}
int totalPrizes = 0;
for ( int i = 0; i < n; i++)
{
totalPrizes += Math.Max(dpLeft[i],
dpRight[i]);
}
Console.Write(totalPrizes + "\n" );
return 0;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 2, 3 };
int n = arr.Length;
minPrizes(arr, n);
}
}
|
Javascript
<script>
function minPrizes(arr, n)
{
let dpLeft = new Array(n);
dpLeft[0] = 1;
for (let i = 1; i < n; i++)
{
if (arr[i] > arr[i - 1])
{
dpLeft[i] = dpLeft[i - 1] + 1;
}
else
{
dpLeft[i] = 1;
}
}
let dpRight = new Array(n);
dpRight[n - 1] = 1;
for (let i = n - 2; i >= 0; i--)
{
if (arr[i] > arr[i + 1])
{
dpRight[i] = dpRight[i + 1] + 1;
}
else
{
dpRight[i] = 1;
}
}
let totalPrizes = 0;
for (let i = 0; i < n; i++)
{
totalPrizes += Math.max(dpLeft[i],
dpRight[i]);
}
document.write(totalPrizes + "</br>" );
return 0;
}
let arr = [ 1, 2, 2, 3 ];
let n = arr.length;
minPrizes(arr, n);
</script>
|
Performance Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(N)
Efficient approach : Space optimization O(1)
In previous approach we the current value dpLeft[i] is only depend upon the previous values i.e. dp[i-1] and current value dpRight[i] is only depend upon the next values i.e. dpRight[i+1] So to optimize the space we can keep track of previous , next and current values by the help of variables which will reduce the space complexity from O(N) to O(1).
Implementation Steps:
- Create 2 variables dpLeft and dpRight to keep track of previous and next values of DP.
- Initialize base case dpLeft = dpRight = 1.
- Create a variable totalPrizes to store current value.
- Iterate over subproblem using loop and update totalPrizes.
- After every iteration update dpLeft and dpRight for further iterations.
- At last return totalPrizes.
Implementation
C++
#include <bits/stdc++.h>
using namespace std;
int minPrizes( int arr[], int n)
{
int dpLeft = 1, dpRight = 1, totalPrizes = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
dpLeft++;
} else {
dpLeft = 1;
}
if (arr[n - i - 1] > arr[n - i]) {
dpRight++;
} else {
dpRight = 1;
}
totalPrizes += max(dpLeft, dpRight);
}
cout << totalPrizes << endl;
return 0;
}
int main()
{
int arr[] = { 1, 2, 2, 3 };
int n = sizeof (arr) / sizeof (arr[0]);
minPrizes(arr, n);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int minPrizes( int arr[], int n)
{
int dpLeft = 1 , dpRight = 1 , totalPrizes = 1 ;
for ( int i = 1 ; i < n; i++) {
if (arr[i] > arr[i - 1 ]) {
dpLeft++;
}
else {
dpLeft = 1 ;
}
if (arr[n - i - 1 ] > arr[n - i]) {
dpRight++;
}
else {
dpRight = 1 ;
}
totalPrizes += Math.max(dpLeft, dpRight);
}
System.out.println(totalPrizes);
return 0 ;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 2 , 3 };
int n = arr.length;
minPrizes(arr, n);
}
}
|
Python3
def minPrizes(arr, n):
dpLeft = 1
dpRight = 1
totalPrizes = 1
for i in range ( 1 , n):
if arr[i] > arr[i - 1 ]:
dpLeft + = 1
else :
dpLeft = 1
if arr[n - i - 1 ] > arr[n - i]:
dpRight + = 1
else :
dpRight = 1
totalPrizes + = max (dpLeft, dpRight)
print (totalPrizes)
return 0
if __name__ = = '__main__' :
arr = [ 1 , 2 , 2 , 3 ]
n = len (arr)
minPrizes(arr, n)
|
C#
using System;
class Program
{
static void MinPrizes( int [] arr, int n)
{
int dpLeft = 1;
int dpRight = 1;
int totalPrizes = 1;
for ( int i = 1; i < n; i++)
{
if (arr[i] > arr[i - 1])
dpLeft += 1;
else
dpLeft = 1;
if (arr[n - i - 1] > arr[n - i])
dpRight += 1;
else
dpRight = 1;
totalPrizes += Math.Max(dpLeft, dpRight);
}
Console.WriteLine(totalPrizes);
}
static void Main()
{
int [] arr = { 1, 2, 2, 3 };
int n = arr.Length;
MinPrizes(arr, n);
}
}
|
Javascript
function minPrizes(arr) {
let dpLeft = 1;
let dpRight = 1;
let totalPrizes = 1;
const n = arr.length;
for (let i = 1; i < n; i++) {
if (arr[i] > arr[i - 1]) {
dpLeft++;
} else {
dpLeft = 1;
}
if (arr[n - i - 1] > arr[n - i]) {
dpRight++;
} else {
dpRight = 1;
}
totalPrizes += Math.max(dpLeft, dpRight);
}
console.log(totalPrizes);
}
const arr = [1, 2, 2, 3];
minPrizes(arr);
|
Performance Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...