You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: content/6_Advanced/Lagrange.mdx
+140-6
Original file line number
Diff line number
Diff line change
@@ -1,18 +1,14 @@
1
1
---
2
2
id: lagrange
3
3
title: 'Lagrangian Relaxation'
4
-
author: Benjamin Qi
4
+
author: Benjamin Qi, Alex Liang, Dong Liu
5
5
description: 'aka Aliens Trick'
6
6
prerequisites:
7
7
- convex-hull
8
8
frequency: 1
9
9
---
10
10
11
-
adding lambda\*smth
12
-
13
-
<Problemsproblems="sample" />
14
-
15
-
## Tutorial
11
+
## Resources
16
12
17
13
<Resources>
18
14
<Resource
@@ -27,6 +23,144 @@ adding lambda\*smth
27
23
/>
28
24
</Resources>
29
25
26
+
## Lagrangian Relaxation
27
+
28
+
Lagrangian Relaxation involves transforming a constraint on a variable into a cost $\lambda$ and binary searching for the optimal $\lambda$.
29
+
30
+
<FocusProblemproblem="sample" />
31
+
32
+
The problem gives us a length $N$ ($1 \le N \le 3 \cdot 10^5$) array of integers in the range $[-10^9,10^9]$. We are given some $K$ ($1 \le K \le N$) and are asked to choose at most $K$ disjoint subarrays such that the sum of elements included in a subarray is maximized.
33
+
34
+
### Intuition
35
+
36
+
The main bottleneck of any dynamic programming solution to this problem is having to store the number of subarrays we have created so far.
37
+
38
+
Let's try to find a way around this. Instead of storing the number of subarrays we have created so far, we assign a penalty of $\lambda$ for creating a new subarray (i.e. every time we create a subarray we penalize our sum by $\lambda$).
39
+
40
+
This leads us to the sub-problem of finding the maximal sum and number of subarrays used if creating a new subarray costs $\lambda$. We can solve this in $\mathcal{O}(N)$ time with dynamic programming.
41
+
42
+
<Spoilertitle="Dynamic Programming Solution">
43
+
Let's have $\texttt{dp}[i][j:\{0,1\}]$ represent the maximum sum if we consider the first $i$ elements, given that $j=0/1$ implies whether
44
+
element $i$ is part of a subarray. Let $\texttt{cnt}[i][j]$ represent the number of
45
+
people used in an optimal arrangement of $\texttt{dp}[i][j]$.
because we either begin a new subarray or we continue an existing subarray.
65
+
</Spoiler>
66
+
67
+
Let $v$ be the maximal achievable sum with $\lambda$ penalty and $c$ be the number of subarrays used to achieve $v$. Then the **maximal possible sum achievable if we use exactly $c$ subarrays is $v+\lambda c$**. Note that we add $\lambda c$ to undo the penalty.
68
+
69
+
Our goal is to find some $\lambda$ such that $c=K$ (assuming $K$ is at most the number of positive elements). As we increase $\lambda$, it makes sense for $c$ to decrease since we are penalizing subarrays more. Thus, we can try to binary search for $\lambda$ to make $c=K$ and set our answer to be $v+\lambda c$ at the optimal $\lambda$.
70
+
71
+
This idea almost works but there are still some very important caveats and conditions that we have not considered.
72
+
73
+
### Geometry
74
+
75
+
Let $f(x)$ be the maximal sum if we use at most $x$ subarrays. We want to find $f(K)$.
76
+
77
+
The first condition is that $f(x)$ **must be concave or convex**. Since $f(x)$ is increasing in this problem, the means that we need $f(x)$ to be concave: $f(x) - f(x - 1) \ge f(x + 1) - f(x)$. In other words, this means that the more subarrays we add, the less we increase the sum by. We can intuitively see that this is true.
78
+
79
+
<Spoilertitle="Proof that our function is concave">
80
+
81
+
We construct a flow graph with source $S$, sink $T$, and $N+1$ additional vertices numbered $1$ to $N+1$. We will have the following edges.
82
+
83
+
- A directed edge from $S$ to $i$ ($1 \le i \le N+1$) with weight $0$ and capacity $1$.
84
+
85
+
- A directed edge from $i$ ($1 \le i \le N+1$) to $T$ with weight $0$ and capacity $1$.
86
+
87
+
- A bidirectional edge from $i$ ($1 \le i \le N$) to $i+1$ with weight $A[i]$ and capacity $1$.
88
+
89
+
$f(x)$ will be the maximum cost $x$-flow through the graph. We can repeatedly find the maximum cost augmenting path $x$ times to get our answer. Because the maximum cost as a function of flow is concave, $f(x)$ will be concave. You can read more about simulating cost flows [here](https://codeforces.com/blog/entry/118391).
90
+
91
+
</Spoiler>
92
+
93
+
Consider the following graphs of $f(x)$ and $f(x)-\lambda x$. In this example, we have $\lambda=5$.
Here is where the fact that $f(x)$ is concave comes in. Because the slope is non-increasing, we know that $f(x) - \lambda x$ will **first increase, then stay the same, and finally decrease**.
103
+
104
+
Let $v(\lambda)$ be the optimal maximal achievable sum with $\lambda$ penalty and $c(\lambda)$ be the number of subarrays used to achieve $v(\lambda)$ (note that if there are multiple such possibilities, we set $c(\lambda)$ to be the **maximal** number of subarrays to achieve $v(\lambda)$). These values can be calculated in $\mathcal{O}(N)$ time using the dynamic programming approach described above.
105
+
106
+
When we assign the penalty of $\lambda$, we are trying to find the maximal sum if creating a subarray reduces our sum by $\lambda$. So $v(\lambda)$ will be the **maximum** of $f(x) - \lambda x$ and $c(\lambda)$ will equal to the rightmost $x$ that **maximizes** $f(x) - \lambda x$.
107
+
108
+
Given the shape of $f(x) - \lambda x$, we know that $f(x) - \lambda x$ will be maximized at all points where $\lambda$ is equal to the slope of $f(x)$ (these points are red in the graph above). If there are no such points it will be maximized at the rightmost point where the slope is less than $\lambda$. So this means that $c(\lambda)$ will be the rightmost $x$ at which the slope of $f(x)$ is still greater or equal to $\lambda$.
109
+
110
+
111
+
Now we know exactly what $\lambda$ represents: $\lambda$ is the slope and $c(\lambda)$ is the rightmost $x$ at which the slope of $f(x)$ is still greater or equal to $\lambda$.
112
+
113
+
We binary search for $\lambda$ and find the highest $\lambda$ such that $c(\lambda) \ge K$. Let the optimal value be $\lambda_{\texttt{opt}}$. Then our answer is $v(\lambda_{\texttt{opt}}) + \lambda_{\texttt{opt}} K$. Note that this works even if $c(\lambda_{\texttt{opt}}) \neq K$ since $c(\lambda_{\texttt{opt}})$ and $K$ will be on the same line with slope $\lambda_{\texttt{opt}}$ in that case.
114
+
115
+
Because calculating $v(\lambda)$ and $c(\lambda)$ with the dynamic programming solution described above will take $\mathcal{O}(N)$ time, this solution runs in $\mathcal{O}(N\log{\sumA[i]})$ time.
116
+
117
+
```cpp
118
+
#include<bits/stdc++.h>
119
+
usingnamespacestd;
120
+
121
+
#definell long long
122
+
123
+
intmain() {
124
+
int n, k;
125
+
cin >> n >> k;
126
+
127
+
int a[n];
128
+
for (int &i : a) {cin>>i; }
129
+
130
+
/**
131
+
* @return the maximum sum along with the number of subarrays used
132
+
* if creating a subarray penalizes the sum by "lmb" and
133
+
* there is no limit to the number of subarrays you can create
0 commit comments