Выполните итерацию один раз и сохраняйте TreeMap
суммы значений W для значений A, меньших или равных данному A, как видно на момент итерации по значению A.
Для new A
, вызовите метод lowerEntry(key)
для суммы W ниже этой новой A.
Запомните наибольшую сумму и верните ее.
Одна итерация равно O (n) , а TreeMap
используется: O (log n) , поэтому решение равно O (n log n) *.
static int sumIncreasing(int[] a, int[] w) {
int maxSum = Integer.MIN_VALUE;
TreeMap<Integer, Integer> sums = new TreeMap<>();
for (int i = 0; i < a.length; i++) {
Entry<Integer, Integer> lowerSum = sums.lowerEntry(a[i]);
int sum = (lowerSum != null ? lowerSum.getValue() + w[i] : w[i]);
sums.put(a[i], sum);
for (Entry<Integer, Integer> e; (e = sums.higherEntry(a[i])) != null && e.getValue() <= sum; )
sums.remove(e.getKey());
if (sum > maxSum)
maxSum = sum;
}
return maxSum;
}
*) Внутренний for
l oop - это O (log n) (амортизированный, наихудший случай), поэтому он не влияет на общую сложность .
Тест
System.out.println(sumIncreasing(new int[] {1, 2, 3, 4}, new int[] {100, 200, 300, 400}));
System.out.println(sumIncreasing(new int[] {4, 2, 3}, new int[] {100, 30, 20}));
Выход
1000
100