Consider a devotee wishing to give offerings to temples along a mountain range. The temples are located in a row at different heights. Each temple should receive at least one offering. If two adjacent temples are at different altitudes, then the temple that is higher up should receive more offerings than the one that is lower down. If two adjacent temples are at the same height, then their offerings relative to each other does not matter. Given the number of temples and the heights of the temples in order, find the minimum number of offerings to bring.**Examples:**

Input : 3 1 2 2 Output : 4 All temples must receive at-least one offering. Now, the second temple is at a higher altitude compared to the first one. Thus it receives one extra offering. The second temple and third temple are at the same height, so we do not need to modify the offerings. Offerings given are therefore: 1, 2, 1 giving a total of 4. Input : 6 1 4 3 6 2 1 Output : 10 We can distribute the offerings in the following way, 1, 2, 1, 3, 2, 1. The second temple has to receive more offerings than the first due to its height being higher. The fourth must receive more than the fifth, which in turn must receive more than the sixth. Thus the total becomes 10.

We notice that each temple can either be above, below, or at the same level as the temple next to it. The offerings required at each temple is equal to the maximum length of the chain of temples at lower height as shown in the image.

**Naive Approach**

To follow the given rule, a temple must be offered at least x+1 where x is maximum of following two.

- Number of temples on left in increasing order.
- Number of temples on right in increasing order.

A naive method of solving this problem would be for each temple, go to the left until altitude increases, and do the same for the right.

## C++

`// Program to find minimum total offerings required ` `#include <iostream> ` `using` `namespace` `std; ` ` ` `// Returns minimum offerings required ` `int` `offeringNumber(` `int` `n, ` `int` `templeHeight[]) ` `{ ` ` ` `int` `sum = 0; ` `// Initialize result ` ` ` ` ` `// Go through all templs one by one ` ` ` `for` `(` `int` `i = 0; i < n; ++i) ` ` ` `{ ` ` ` `// Go to left while height keeps increasing ` ` ` `int` `left = 0, right = 0; ` ` ` `for` `(` `int` `j = i - 1; j >= 0; --j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < templeHeight[j + 1]) ` ` ` `++left; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// Go to right while height keeps increasing ` ` ` `for` `(` `int` `j = i + 1; j < n; ++j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < templeHeight[j - 1]) ` ` ` `++right; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// This temple should offer maximum of two ` ` ` `// values to follow the rule. ` ` ` `sum += max(right, left) + 1; ` ` ` `} ` ` ` ` ` `return` `sum; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `arr1[3] = {1, 2, 2}; ` ` ` `cout << offeringNumber(3, arr1) << ` `"\n"` `; ` ` ` `int` `arr2[6] = {1, 4, 3, 6, 2, 1}; ` ` ` `cout << offeringNumber(6, arr2) << ` `"\n"` `; ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Program to find minimum ` `// total offerings required ` `import` `java.io.*; ` ` ` `class` `GFG ` `{ ` ` ` `// Returns minimum ` `// offerings required ` `static` `int` `offeringNumber(` `int` `n, ` ` ` `int` `templeHeight[]) ` `{ ` ` ` `int` `sum = ` `0` `; ` `// Initialize result ` ` ` ` ` `// Go through all ` ` ` `// temples one by one ` ` ` `for` `(` `int` `i = ` `0` `; i < n; ++i) ` ` ` `{ ` ` ` `// Go to left while ` ` ` `// height keeps increasing ` ` ` `int` `left = ` `0` `, right = ` `0` `; ` ` ` `for` `(` `int` `j = i - ` `1` `; j >= ` `0` `; --j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < ` ` ` `templeHeight[j + ` `1` `]) ` ` ` `++left; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// Go to right while ` ` ` `// height keeps increasing ` ` ` `for` `(` `int` `j = i + ` `1` `; j < n; ++j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < ` ` ` `templeHeight[j - ` `1` `]) ` ` ` `++right; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// This temple should offer ` ` ` `// maximum of two values ` ` ` `// to follow the rule. ` ` ` `sum += Math.max(right, left) + ` `1` `; ` ` ` `} ` ` ` ` ` `return` `sum; ` `} ` ` ` `// Driver code ` `public` `static` `void` `main (String[] args) ` `{ ` `int` `arr1[] = {` `1` `, ` `2` `, ` `2` `}; ` `System.out.println(offeringNumber(` `3` `, arr1)); ` `int` `arr2[] = {` `1` `, ` `4` `, ` `3` `, ` ` ` `6` `, ` `2` `, ` `1` `}; ` `System.out.println(offeringNumber(` `6` `, arr2)); ` `} ` `} ` ` ` `// This code is contributed by akt_mit ` |

*chevron_right*

*filter_none*

## Python3

`# Program to find minimum total ` `# offerings required. ` ` ` `# Returns minimum offerings required ` `def` `offeringNumber(n, templeHeight): ` ` ` `sum` `=` `0` `# Initialize result ` ` ` ` ` `# Go through all templs one by one ` ` ` `for` `i ` `in` `range` `(n): ` ` ` ` ` `# Go to left while height ` ` ` `# keeps increasing ` ` ` `left ` `=` `0` ` ` `right ` `=` `0` ` ` `for` `j ` `in` `range` `(i ` `-` `1` `, ` `-` `1` `, ` `-` `1` `): ` ` ` `if` `(templeHeight[j] < templeHeight[j ` `+` `1` `]): ` ` ` `left ` `+` `=` `1` ` ` `else` `: ` ` ` `break` ` ` ` ` `# Go to right while height ` ` ` `# keeps increasing ` ` ` `for` `j ` `in` `range` `(i ` `+` `1` `, n): ` ` ` `if` `(templeHeight[j] < templeHeight[j ` `-` `1` `]): ` ` ` `right ` `+` `=` `1` ` ` `else` `: ` ` ` `break` ` ` ` ` `# This temple should offer maximum ` ` ` `# of two values to follow the rule. ` ` ` `sum` `+` `=` `max` `(right, left) ` `+` `1` ` ` `return` `sum` ` ` `# Driver Code ` `arr1 ` `=` `[` `1` `, ` `2` `, ` `2` `] ` `print` `(offeringNumber(` `3` `, arr1)) ` `arr2 ` `=` `[` `1` `, ` `4` `, ` `3` `, ` `6` `, ` `2` `, ` `1` `] ` `print` `(offeringNumber(` `6` `, arr2)) ` ` ` `# This code is contributed ` `# by sahilshelangia ` |

*chevron_right*

*filter_none*

## C#

`// Program to find minimum ` `// total offerings required ` `using` `System; ` ` ` `class` `GFG ` `{ ` ` ` `// Returns minimum ` `// offerings required ` `static` `int` `offeringNumber(` `int` `n, ` ` ` `int` `[]templeHeight) ` `{ ` ` ` `int` `sum = 0; ` `// Initialize result ` ` ` ` ` `// Go through all ` ` ` `// temples one by one ` ` ` `for` `(` `int` `i = 0; i < n; ++i) ` ` ` `{ ` ` ` `// Go to left while ` ` ` `// height keeps increasing ` ` ` `int` `left = 0, right = 0; ` ` ` `for` `(` `int` `j = i - 1; j >= 0; --j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < ` ` ` `templeHeight[j + 1]) ` ` ` `++left; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// Go to right while ` ` ` `// height keeps increasing ` ` ` `for` `(` `int` `j = i + 1; j < n; ++j) ` ` ` `{ ` ` ` `if` `(templeHeight[j] < ` ` ` `templeHeight[j - 1]) ` ` ` `++right; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// This temple should offer ` ` ` `// maximum of two values ` ` ` `// to follow the rule. ` ` ` `sum += Math.Max(right, left) + 1; ` ` ` `} ` ` ` ` ` `return` `sum; ` `} ` ` ` `// Driver code ` `static` `public` `void` `Main () ` `{ ` ` ` `int` `[]arr1 = {1, 2, 2}; ` ` ` `Console.WriteLine(offeringNumber(3, arr1)); ` ` ` ` ` `int` `[]arr2 = {1, 4, 3, ` ` ` `6, 2, 1}; ` ` ` `Console.WriteLine(offeringNumber(6, arr2)); ` `} ` `} ` ` ` `// This code is contributed by aj_36 ` |

*chevron_right*

*filter_none*

## PHP

`<?php ` `// Program to find minimum total offerings required ` ` ` `// Returns minimum offerings required ` `function` `offeringNumber(` `$n` `, ` `$templeHeight` `) ` `{ ` ` ` `$sum` `= 0; ` `// Initialize result ` ` ` ` ` `// Go through all templs one by one ` ` ` `for` `(` `$i` `= 0; ` `$i` `< ` `$n` `; ++` `$i` `) ` ` ` `{ ` ` ` `// Go to left while height keeps increasing ` ` ` `$left` `= 0; ` `$right` `= 0; ` ` ` `for` `(` `$j` `= ` `$i` `- 1; ` `$j` `>= 0; --` `$j` `) ` ` ` `{ ` ` ` `if` `(` `$templeHeight` `[` `$j` `] < ` `$templeHeight` `[` `$j` `+ 1]) ` ` ` `++` `$left` `; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// Go to right while height keeps increasing ` ` ` `for` `(` `$j` `= ` `$i` `+ 1; ` `$j` `< ` `$n` `; ++` `$j` `) ` ` ` `{ ` ` ` `if` `(` `$templeHeight` `[` `$j` `] < ` `$templeHeight` `[` `$j` `- 1]) ` ` ` `++` `$right` `; ` ` ` `else` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// This temple should offer maximum of two ` ` ` `// values to follow the rule. ` ` ` `$sum` `+= max(` `$right` `, ` `$left` `) + 1; ` ` ` `} ` ` ` ` ` `return` `$sum` `; ` `} ` ` ` `// Driver code ` ` ` `$arr1` `= ` `array` `(1, 2, 2); ` ` ` `echo` `offeringNumber(3, ` `$arr1` `) , ` `"\n"` `; ` ` ` `$arr2` `= ` `array` `(1, 4, 3, 6, 2, 1); ` ` ` `echo` `offeringNumber(6, ` `$arr2` `) ,` `"\n"` `; ` ` ` `// This code is contributed by ajit ` `?> ` |

*chevron_right*

*filter_none*

**Output:**

4 10

**Time complexity:** O(n^{2}) **Space complexity:** O(1)

**Dynamic Programming Approach**

By using Dynamic Programming, we can improve the time complexity. In this method, we create a structure of length n which maintains the maximum decreasing chain to the left of each temple and the maximum decreasing chain to the right of each temple. We go through once from 0 to N setting the value of left for each temple. We then go from N to 0 setting the value of right for each temple. We then compare the two and pick the maximum for each temple.

## C++

`// Program to find total offerings required ` `#include <iostream> ` `using` `namespace` `std; ` ` ` `// To store count of increasing order temples ` `// on left and right (including current temple) ` `struct` `Temple ` `{ ` ` ` `int` `L; ` ` ` `int` `R; ` `}; ` ` ` `// Returns count of minimum offerings for ` `// n temples of given heights. ` `int` `offeringNumber(` `int` `n, ` `int` `templeHeight[]) ` `{ ` ` ` `// Initialize counts for all temples ` ` ` `Temple chainSize[n]; ` ` ` `for` `(` `int` `i = 0; i < n; ++i) ` ` ` `{ ` ` ` `chainSize[i].L = -1; ` ` ` `chainSize[i].R = -1; ` ` ` `} ` ` ` ` ` `// Values corner temples ` ` ` `chainSize[0].L = 1; ` ` ` `chainSize[n-1].R = 1; ` ` ` ` ` `// Filling left and right values using same ` ` ` `// values of previous(or next) ` ` ` `for` `(` `int` `i=1; i<n; ++i) ` ` ` `{ ` ` ` `if` `(templeHeight[i - 1] < templeHeight[i]) ` ` ` `chainSize[i].L = chainSize[i - 1].L + 1; ` ` ` `else` ` ` `chainSize[i].L = 1; ` ` ` `} ` ` ` `for` `(` `int` `i=n-2; i>=0; --i) ` ` ` `{ ` ` ` `if` `(templeHeight[i + 1] < templeHeight[i]) ` ` ` `chainSize[i].R = chainSize[i + 1].R + 1; ` ` ` `else` ` ` `chainSize[i].R = 1; ` ` ` `} ` ` ` ` ` `// Computing max of left and right for all ` ` ` `// temples and returing sum. ` ` ` `int` `sum = 0; ` ` ` `for` `(` `int` `i = 0; i < n; ++i) ` ` ` `sum += max(chainSize[i].L, chainSize[i].R); ` ` ` `return` `sum; ` `} ` ` ` `// Driver function ` `int` `main() ` `{ ` ` ` `int` `arr1[3] = {1, 2, 2}; ` ` ` `cout << offeringNumber(3, arr1) << ` `"\n"` `; ` ` ` `int` `arr2[6] = {1, 4, 3, 6, 2, 1}; ` ` ` `cout << offeringNumber(6, arr2) << ` `"\n"` `; ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to find temple ` `# offerings required ` `from` `typing ` `import` `List` ` ` `# To store count of increasing order temples ` `# on left and right (including current temple) ` `class` `Temple: ` ` ` `def` `__init__(` `self` `, l: ` `int` `, r: ` `int` `): ` ` ` ` ` `self` `.L ` `=` `l ` ` ` `self` `.R ` `=` `r ` ` ` `# Returns count of minimum offerings for ` `# n temples of given heights. ` `def` `offeringNumber(n: ` `int` `, ` ` ` `templeHeight: ` `List` `[` `int` `]) ` `-` `> ` `int` `: ` ` ` ` ` `# Initialize counts for all temples ` ` ` `chainSize ` `=` `[` `0` `] ` `*` `n ` ` ` ` ` `for` `i ` `in` `range` `(n): ` ` ` `chainSize[i] ` `=` `Temple(` `-` `1` `, ` `-` `1` `) ` ` ` ` ` `# Values corner temples ` ` ` `chainSize[` `0` `].L ` `=` `1` ` ` `chainSize[` `-` `1` `].R ` `=` `1` ` ` ` ` `# Filling left and right values ` ` ` `# using same values of previous(or next ` ` ` `for` `i ` `in` `range` `(` `1` `, n): ` ` ` `if` `templeHeight[i ` `-` `1` `] < templeHeight[i]: ` ` ` `chainSize[i].L ` `=` `chainSize[i ` `-` `1` `].L ` `+` `1` ` ` `else` `: ` ` ` `chainSize[i].L ` `=` `1` ` ` ` ` `for` `i ` `in` `range` `(n ` `-` `2` `, ` `-` `1` `, ` `-` `1` `): ` ` ` `if` `templeHeight[i ` `+` `1` `] < templeHeight[i]: ` ` ` `chainSize[i].R ` `=` `chainSize[i ` `+` `1` `].R ` `+` `1` ` ` `else` `: ` ` ` `chainSize[i].R ` `=` `1` ` ` ` ` `# Computing max of left and right for all ` ` ` `# temples and returing sum ` ` ` `sm ` `=` `0` ` ` `for` `i ` `in` `range` `(n): ` ` ` `sm ` `+` `=` `max` `(chainSize[i].L, ` ` ` `chainSize[i].R) ` ` ` ` ` `return` `sm ` ` ` `# Driver code ` `if` `__name__ ` `=` `=` `'__main__'` `: ` ` ` ` ` `arr1 ` `=` `[ ` `1` `, ` `2` `, ` `2` `] ` ` ` `print` `(offeringNumber(` `3` `, arr1)) ` ` ` ` ` `arr2 ` `=` `[ ` `1` `, ` `4` `, ` `3` `, ` `6` `, ` `2` `, ` `1` `] ` ` ` `print` `(offeringNumber(` `6` `, arr2)) ` ` ` `# This code is contributed by Rajat Srivastava ` |

*chevron_right*

*filter_none*

**Output:**

4 10

**Time complexity: **O(n) **Space complexity:** O(n)

This article is contributed by **Aditya Kamath**. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Paths requiring minimum number of jumps to reach end of array
- Length of longest increasing absolute even subsequence
- Count N digits numbers with sum divisible by K
- Maximize length of longest increasing prime subsequence from the given array
- Longest increasing subsequence which forms a subarray in the sorted representation of the array
- Maximum score assigned to a subsequence of numerically consecutive and distinct array elements
- Maximum subsequence sum possible by multiplying each element by its index
- Count unimodal and non-unimodal permutations of first N natural numbers
- Number from a range [L, R] having Kth minimum cost of conversion to 1 by given operations
- Generate a combination of minimum coins that sums to a given value
- Longest subsequence forming an Arithmetic Progression (AP)
- Maximize sum of remaining elements after every removal of the array half with greater sum
- Length of longest increasing prime subsequence from a given array
- Maximize cost to empty an array by removing contiguous subarrays of equal elements