A subsequence of nums having length k and consisting of indicesi0 < i1 < ... < ik-1 is balanced if the following holds:
nums[ij] - nums[ij-1] >= ij - ij-1, for every j in the range [1, k - 1].
A subsequence of nums having length 1 is considered balanced.
Return _an integer denoting themaximum possible sum of elements in a
balanced subsequence of _nums.
A subsequence of an array is a new non-empty array that is formed from the original array by deleting some (possibly none) of the elements without disturbing the relative positions of the remaining elements.
Input: nums =[3,3,5,6] Output:14 Explanation: In this example, the subsequence [3,5,6] consisting of indices 0,2, and 3 can be selected. nums[2]- nums[0]>=2-0. nums[3]- nums[2]>=3-2. Hence, it is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums. The subsequence consisting of indices 1,2, and 3is also valid. It can be shown that it is not possible to get a balanced subsequence with a sum greater than 14.
Input: nums =[5,-1,-3,8] Output:13 Explanation: In this example, the subsequence [5,8] consisting of indices 0 and 3 can be selected. nums[3]- nums[0]>=3-0. Hence, it is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums. It can be shown that it is not possible to get a balanced subsequence with a sum greater than 13.
Input: nums =[-2,-1] Output:-1 Explanation: In this example, the subsequence [-1] can be selected. It is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums.
To maximize the sum of a balanced subsequence, we want to extend the subsequence as much as possible. For each index, we can use dynamic programming to track the best sum ending at each position, and use a Fenwick Tree (Binary Indexed Tree) to efficiently query and update the best sum for valid previous indices. Since the difference nums[j] - j must be non-decreasing, we use coordinate compression on nums[i] - i.
classSolution {
publiclongmaxBalancedSubsequenceSum(int[] nums) {
int n = nums.length;
long[] keys =newlong[n];
for (int i = 0; i < n; ++i) keys[i]= (long)nums[i]- i;
long[] uniq = Arrays.stream(keys).distinct().sorted().toArray();
Map<Long, Integer> idx =new HashMap<>();
for (int i = 0; i < uniq.length; ++i) idx.put(uniq[i], i);
long[] bit =newlong[uniq.length+2];
Arrays.fill(bit, Long.MIN_VALUE);
long ans = Long.MIN_VALUE;
for (int i = 0; i < n; ++i) {
int k = idx.get((long)nums[i]- i);
long best = Long.MIN_VALUE;
for (int j = k+1; j > 0; j -= j&-j) best = Math.max(best, bit[j]);
long cur = nums[i];
if (best != Long.MIN_VALUE) cur += best;
for (int j = k+1; j < bit.length; j += j&-j) bit[j]= Math.max(bit[j], cur);
ans = Math.max(ans, cur);
}
return ans;
}
}
classSolution {
funmaxBalancedSubsequenceSum(nums: IntArray): Long {
val n = nums.size
val keys = LongArray(n) { nums[it].toLong() - it }
val uniq = keys.distinct().sorted()
val idx = uniq.withIndex().associate { it.value to it.index }
val bit = LongArray(uniq.size+2) { Long.MIN_VALUE }
var ans = Long.MIN_VALUE
for (i in0 until n) {
val k = idx[nums[i].toLong() - i]!!var best = Long.MIN_VALUE
var j = k+1while (j > 0) {
best = maxOf(best, bit[j])
j -= j and -j
}
var cur = nums[i].toLong()
if (best !=Long.MIN_VALUE) cur += best
j = k+1while (j < bit.size) {
bit[j] = maxOf(bit[j], cur)
j += j and -j
}
ans = maxOf(ans, cur)
}
return ans
}
}
classSolution:
defmaxBalancedSubsequenceSum(self, nums: list[int]) -> int:
n = len(nums)
keys = [nums[i] - i for i in range(n)]
uniq = sorted(set(keys))
idx = {v: i for i, v in enumerate(uniq)}
bit = [float('-inf')] * (len(uniq)+2)
defquery(i):
res = float('-inf')
i +=1while i >0:
res = max(res, bit[i])
i -= i &-i
return res
defupdate(i, val):
i +=1while i < len(bit):
bit[i] = max(bit[i], val)
i += i &-i
ans = float('-inf')
for i in range(n):
k = idx[nums[i] - i]
best = query(k)
cur = nums[i]
if best != float('-inf'):
cur += best
update(k, cur)
ans = max(ans, cur)
return ans
impl Solution {
pubfnmax_balanced_subsequence_sum(nums: Vec<i32>) -> i64 {
let n = nums.len();
letmut keys: Vec<i64>= (0..n).map(|i| nums[i] asi64- i asi64).collect();
keys.sort();
keys.dedup();
letmut bit =vec![i64::MIN; keys.len()+2];
letmut ans =i64::MIN;
for (i, &x) in nums.iter().enumerate() {
let k = keys.binary_search(&(x asi64- i asi64)).unwrap();
letmut best =i64::MIN;
letmut j = k+1;
while j >0 {
best = best.max(bit[j]);
j -= j & (!j +1);
}
letmut cur = x asi64;
if best !=i64::MIN {
cur += best;
}
j = k+1;
while j < bit.len() {
bit[j] = bit[j].max(cur);
j += j & (!j +1);
}
ans = ans.max(cur);
}
ans
}
}