Repository navigation
Expand file tree
/
Copy pathPotd
More file actions
91 lines (81 loc) · 2.45 KB
/
Copy pathPotd
File metadata and controls
91 lines (81 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Solution {
private static class MultiSet {
TreeMap<Integer, Integer> counts = new TreeMap<>();
int size = 0;
long sum = 0;
void add(int value) {
counts.put(value, counts.getOrDefault(value, 0) + 1);
++size;
sum += value;
}
void remove(int value) {
int count = counts.get(value);
if (count == 1) {
counts.remove(value);
} else {
counts.put(value, count - 1);
}
--size;
sum -= value;
}
int min() {
return counts.firstKey();
}
int max() {
return counts.lastKey();
}
}
private long[] getCosts(int[] nums, int x) {
int n = nums.length;
long[] ops = new long[n];
MultiSet left = new MultiSet();
MultiSet right = new MultiSet();
for (int i = 0; i < n; ++i) {
int value = nums[i];
if (left.size == 0 || value <= left.max()) {
left.add(value);
} else {
right.add(value);
}
if (i >= x) {
value = nums[i - x];
if (left.counts.containsKey(value)) {
left.remove(value);
} else {
right.remove(value);
}
}
if (left.size > right.size + 1) {
value = left.max();
left.remove(value);
right.add(value);
} else if (left.size < right.size) {
value = right.min();
right.remove(value);
left.add(value);
}
if (i >= x - 1) {
long mid = left.max();
ops[i] =
mid * left.size - left.sum + right.sum - mid * right.size;
}
}
return ops;
}
public long minOperations(int[] nums, int x, int k) {
int n = nums.length;
long[] ops = getCosts(nums, x);
long[] pre = new long[n + 1];
long[] cur = new long[n + 1];
for (int j = 1; j <= k; ++j) {
Arrays.fill(cur, Long.MAX_VALUE);
for (int i = j * x; i <= n; ++i) {
cur[i] = Math.min(cur[i - 1], pre[i - x] + ops[i - 1]);
}
long[] temp = pre;
pre = cur;
cur = temp;
}
return pre[n];
}
}