Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to Find Out the Maximum Final Power of a List in Python
The power of a list is defined as the sum of (index + 1) * value_at_index over all indices. We can represent this mathematically as:
$$\displaystyle\sum\limits_{i=0}^{n-1} (i+1)\times list[i]$$
Given a list of N positive integers, we can select any single value and move it to any position (beginning, end, or leave it unchanged). Our goal is to find the maximum possible final power of the list, with the result modded by 10^9 + 7.
Understanding the Problem
Let's first understand what power means with a simple example:
def calculate_power(nums):
power = 0
for i, value in enumerate(nums):
power += (i + 1) * value
return power
# Original list
nums = [4, 2, 1]
original_power = calculate_power(nums)
print(f"Original power: {original_power}")
# If we move 4 to the end: [2, 1, 4]
moved_list = [2, 1, 4]
new_power = calculate_power(moved_list)
print(f"Power after moving 4 to end: {new_power}")
Original power: 13 Power after moving 4 to end: 16
Algorithm Approach
The solution uses a convex hull optimization technique to efficiently find the optimal position for each element. Here's how it works:
- Prefix sums: Build cumulative sums to quickly calculate contributions
- Convex hull: Maintain a hull of optimal positions using intersection points
- Binary search: For each element, find the best position using binary search
Complete Solution
import bisect
class Solution:
def solve(self, A):
# Build prefix sums and calculate base power
P = [0]
base = 0
for i, x in enumerate(A, 1):
P.append(P[-1] + x)
base += i * x
# Helper function to evaluate benefit at position j
def eval_at(j, x):
return -j * x + P[j]
# Helper function to find intersection point
def intersection(j1, j2):
return (P[j2] - P[j1]) / (j2 - j1)
# Build convex hull for optimization
hull = [-1]
indexes = [0]
for j in range(1, len(P)):
while hull and intersection(indexes[-1], j) <= hull[-1]:
hull.pop()
indexes.pop()
hull.append(intersection(indexes[-1], j))
indexes.append(j)
# Find maximum power by trying each element
ans = base
for i, x in enumerate(A):
j = bisect.bisect(hull, x)
j = max(j - 1, 0)
ans = max(ans, base + eval_at(i, x) - eval_at(indexes[j], x))
return ans % (10 ** 9 + 7)
# Test the solution
ob = Solution()
result = ob.solve([4, 2, 1])
print(f"Maximum power: {result}")
Maximum power: 16
Step-by-Step Verification
Let's verify the result by checking all possible moves:
def find_max_power_brute_force(nums):
def calculate_power(arr):
return sum((i + 1) * val for i, val in enumerate(arr))
max_power = calculate_power(nums)
best_config = nums.copy()
# Try moving each element to each position
for i in range(len(nums)):
element = nums[i]
remaining = nums[:i] + nums[i+1:]
# Try inserting at each position
for pos in range(len(nums)):
new_list = remaining[:pos] + [element] + remaining[pos:]
power = calculate_power(new_list)
if power > max_power:
max_power = power
best_config = new_list
return max_power, best_config
nums = [4, 2, 1]
max_power, best_config = find_max_power_brute_force(nums)
print(f"Maximum power: {max_power}")
print(f"Best configuration: {best_config}")
Maximum power: 16 Best configuration: [2, 1, 4]
Conclusion
The optimal solution uses convex hull optimization to achieve O(n log n) time complexity. By moving the largest element to the highest-weighted position (end of the list), we maximize the final power of the list.
---