Improve language
This commit is contained in:
parent
e08db81f24
commit
a67a72c17c
211
chapter07.tex
211
chapter07.tex
|
@ -348,7 +348,6 @@ to form an empty sum.
|
||||||
Otherwise we calculate the sum of all values
|
Otherwise we calculate the sum of all values
|
||||||
of the form $\texttt{solve}(x-c)$ where $c$ is in \texttt{coins}.
|
of the form $\texttt{solve}(x-c)$ where $c$ is in \texttt{coins}.
|
||||||
|
|
||||||
|
|
||||||
The following code constructs an array
|
The following code constructs an array
|
||||||
$\texttt{count}$ such that
|
$\texttt{count}$ such that
|
||||||
$\texttt{count}[x]$ equals
|
$\texttt{count}[x]$ equals
|
||||||
|
@ -393,15 +392,13 @@ possibilities of dynamic programming.
|
||||||
|
|
||||||
\index{longest increasing subsequence}
|
\index{longest increasing subsequence}
|
||||||
|
|
||||||
Let us consider the following problem:
|
Our first problem is to find the
|
||||||
Given an array that contains $n$
|
|
||||||
numbers,
|
|
||||||
our task is to find the
|
|
||||||
\key{longest increasing subsequence}
|
\key{longest increasing subsequence}
|
||||||
of the array.
|
in an array \texttt{t} of $n$ elements.
|
||||||
This is a sequence of array elements
|
This is a maximum-length
|
||||||
|
sequence of array elements
|
||||||
that goes from left to right,
|
that goes from left to right,
|
||||||
and each element of the sequence is larger
|
and each element in the sequence is larger
|
||||||
than the previous element.
|
than the previous element.
|
||||||
For example, in the array
|
For example, in the array
|
||||||
|
|
||||||
|
@ -462,65 +459,81 @@ contains 4 elements:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Let $f(k)$ be the length of the
|
Let $\texttt{length}(k)$ denote
|
||||||
|
the length of the
|
||||||
longest increasing subsequence
|
longest increasing subsequence
|
||||||
that ends at position $k$.
|
that ends at position $k$.
|
||||||
Using this function, the answer to the problem
|
Thus, if we calculate all values of
|
||||||
is the largest of the values
|
$\texttt{length}(k)$ where $0 \le k \le n-1$,
|
||||||
$f(0),f(1),\ldots,f(n-1)$.
|
we will find out the length of the
|
||||||
For example, in the above array
|
longest increasing subsequence.
|
||||||
the values of the function are as follows:
|
For example, the values of the function
|
||||||
|
for the above array are as follows:
|
||||||
\[
|
\[
|
||||||
\begin{array}{lcl}
|
\begin{array}{lcl}
|
||||||
f(0) & = & 1 \\
|
\texttt{length}(0) & = & 1 \\
|
||||||
f(1) & = & 1 \\
|
\texttt{length}(1) & = & 1 \\
|
||||||
f(2) & = & 2 \\
|
\texttt{length}(2) & = & 2 \\
|
||||||
f(3) & = & 1 \\
|
\texttt{length}(3) & = & 1 \\
|
||||||
f(4) & = & 3 \\
|
\texttt{length}(4) & = & 3 \\
|
||||||
f(5) & = & 2 \\
|
\texttt{length}(5) & = & 2 \\
|
||||||
f(6) & = & 4 \\
|
\texttt{length}(6) & = & 4 \\
|
||||||
f(7) & = & 2 \\
|
\texttt{length}(7) & = & 2 \\
|
||||||
\end{array}
|
\end{array}
|
||||||
\]
|
\]
|
||||||
|
|
||||||
When calculating the value of $f(k)$,
|
For example, $\texttt{length}(6)=4$,
|
||||||
there are two possibilities how the subsequence
|
because the longest increasing subsequence
|
||||||
that ends at position $k$ is constructed:
|
that ends at position 6 consists of 4 elements.
|
||||||
\begin{enumerate}
|
|
||||||
\item The subsequence
|
|
||||||
only contains the element at position $k$. In this case $f(k)=1$.
|
|
||||||
\item The subsequence contains a subsequence
|
|
||||||
that ends at position $i$ where $i<k$,
|
|
||||||
followed by the element at position $k$.
|
|
||||||
The element at position $i$ must be smaller
|
|
||||||
than the element at position $k$.
|
|
||||||
In this case $f(k)=f(i)+1$.
|
|
||||||
\end{enumerate}
|
|
||||||
|
|
||||||
For example, in the above example $f(6)=4$,
|
To calculate a value of $\texttt{length}(k)$,
|
||||||
because the subsequence $[2,5,7]$ of length 3
|
we should find a position $i<k$
|
||||||
ends at position 4, and by adding the element
|
for which $\texttt{t}[i]<\texttt{t}[k]$
|
||||||
at position 6 to this subsequence,
|
and $\texttt{length}(i)$ is as large as possible.
|
||||||
we get the optimal subsequence $[2,5,7,8]$ of length 4.
|
Then we know that
|
||||||
|
$\texttt{length}(k)=\texttt{length}(i)+1$,
|
||||||
|
because this is an optimal way to add
|
||||||
|
$\texttt{t}[k]$ to a subsequence.
|
||||||
|
However, if there is no such position $i$,
|
||||||
|
then $\texttt{length}(k)=1$,
|
||||||
|
which means that the subsequence only contains
|
||||||
|
$\texttt{t}[k]$.
|
||||||
|
|
||||||
An easy way to calculate the
|
Since all values of the function can be calculated
|
||||||
value of $f(k)$ is to
|
from its smaller values,
|
||||||
go through all previous values
|
we can use dynamic programming.
|
||||||
$f(0),f(1),\ldots,f(k-1)$ and select the best solution.
|
In the following code, the values
|
||||||
The time complexity of such an algorithm is $O(n^2)$.
|
of the function will be stored in an array
|
||||||
Surprisingly, it is also possible to solve the
|
$\texttt{length}$.
|
||||||
problem in $O(n \log n)$ time. Can you see how?
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
for (int k = 0; k < n; k++) {
|
||||||
|
length[k] = 1;
|
||||||
|
for (int i = 0; i < k; i++) {
|
||||||
|
if (t[i] < t[k]) {
|
||||||
|
length[k] = max(length[k],length[i]+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
This code works in $O(n^2)$ time,
|
||||||
|
because it consists of two nested loops.
|
||||||
|
However, it is also possible to implement
|
||||||
|
the dynamic programming calculation
|
||||||
|
more efficiently in $O(n \log n)$ time.
|
||||||
|
Can you find a way to do this?
|
||||||
|
|
||||||
\section{Paths in a grid}
|
\section{Paths in a grid}
|
||||||
|
|
||||||
Our next problem is to find a path
|
Our next problem is to find a path
|
||||||
in an $n \times n$ grid
|
|
||||||
from the upper-left corner to
|
from the upper-left corner to
|
||||||
the lower-right corner such that
|
the lower-right corner
|
||||||
|
of an $n \times n$ grid, such that
|
||||||
we only move down and right.
|
we only move down and right.
|
||||||
Each square contains a number,
|
Each square contains a value,
|
||||||
and the path should be constructed so
|
and the path should be constructed so
|
||||||
that the sum of the numbers along
|
that the sum of the values along
|
||||||
the path is as large as possible.
|
the path is as large as possible.
|
||||||
|
|
||||||
The following picture shows an optimal
|
The following picture shows an optimal
|
||||||
|
@ -566,19 +579,29 @@ path in a grid:
|
||||||
\end{scope}
|
\end{scope}
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
The sum of the numbers on the path is 67,
|
The sum of the values on the path is 67,
|
||||||
and this is the largest possible sum on a path
|
and this is the largest possible sum on a path
|
||||||
from the
|
from the
|
||||||
upper-left corner to the lower-right corner.
|
upper-left corner to the lower-right corner.
|
||||||
|
|
||||||
We can approach the problem by
|
Assume that the rows and columns of the
|
||||||
calculating for each square $(y,x)$
|
grid are numbered from 1 to $n$,
|
||||||
the maximum sum on a path
|
and $\texttt{value}[y][x]$ equals the value
|
||||||
from the upper-left corner to square $(y,x)$.
|
of square $(y,x)$.
|
||||||
Let $f(y,x)$ denote this sum,
|
Let $\texttt{sum}(y,x)$ denote the maximum
|
||||||
so $f(n,n)$ is the maximum sum on a path
|
sum on a path from the upper-left corner
|
||||||
|
to square $(y,x)$.
|
||||||
|
Now $\texttt{sum}(n,n)$ tells us
|
||||||
|
the maximum sum
|
||||||
from the upper-left corner to
|
from the upper-left corner to
|
||||||
the lower-right corner.
|
the lower-right corner.
|
||||||
|
For example, in the above grid,
|
||||||
|
$\texttt{sum}(5,5)=67$.
|
||||||
|
|
||||||
|
We can recursively calculate the sums
|
||||||
|
as follows:
|
||||||
|
\[ \texttt{sum}(y,x) = \max(\texttt{sum}(y,x-1),\texttt{sum}(y-1,x))+\texttt{value}[y][x]\]
|
||||||
|
|
||||||
|
|
||||||
The recursive formula is based on the observation
|
The recursive formula is based on the observation
|
||||||
that a path that ends at square $(y,x)$
|
that a path that ends at square $(y,x)$
|
||||||
|
@ -597,27 +620,31 @@ or square $(y-1,x)$:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
Let $r(y,x)$ denote the number in square $(y,x)$.
|
Thus, we select the direction that maximizes
|
||||||
The base cases for the recursive function
|
the sum.
|
||||||
are as follows:
|
We assume that $\texttt{sum}(y,x)=0$
|
||||||
|
if $y=0$ or $x=0$ (because no such paths exist),
|
||||||
|
so the recursive formula also works when $y=1$ or $x=1$.
|
||||||
|
|
||||||
\[
|
Since the function \texttt{sum} has two parameters,
|
||||||
\begin{array}{lcl}
|
the dynamic programming array also has two dimensions.
|
||||||
f(1,1) & = & r(1,1) \\
|
For example, we can use an array
|
||||||
f(1,x) & = & f(1,x-1)+r(1,x) \\
|
\begin{lstlisting}
|
||||||
f(y,1) & = & f(y-1,1)+r(y,1)\\
|
int sum[N][N];
|
||||||
\end{array}
|
\end{lstlisting}
|
||||||
\]
|
and calculate the sums as follows:
|
||||||
|
\begin{lstlisting}
|
||||||
|
for (int y = 1; y <= n; y++) {
|
||||||
|
for (int x = 1; x <= n; x++) {
|
||||||
|
sum[y][x] = max(sum[y][x-1],sum[y-1][x])+value[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
In the general case there are two
|
Note that it is not needed to separately handle the
|
||||||
possible paths, and we should select the path
|
cases where $y=1$ or $x=1$, because we use a
|
||||||
that produces the larger sum:
|
one-indexed array whose values are initially zeros.
|
||||||
\[ f(y,x) = \max(f(y,x-1),f(y-1,x))+r(y,x)\]
|
The time complexity of the algorithm is $O(n^2)$.
|
||||||
|
|
||||||
The time complexity of the solution is $O(n^2)$,
|
|
||||||
because each value $f(y,x)$ can be calculated
|
|
||||||
in constant time using the values of the
|
|
||||||
adjacent squares.
|
|
||||||
|
|
||||||
\section{Knapsack}
|
\section{Knapsack}
|
||||||
|
|
||||||
|
@ -625,10 +652,10 @@ adjacent squares.
|
||||||
|
|
||||||
\key{Knapsack} is a classic problem where we
|
\key{Knapsack} is a classic problem where we
|
||||||
are given $n$ objects with weights
|
are given $n$ objects with weights
|
||||||
$p_1,p_2,\ldots,p_n$ and values
|
$w_1,w_2,\ldots,w_n$ and values
|
||||||
$a_1,a_2,\ldots,a_n$.
|
$v_1,v_2,\ldots,v_n$.
|
||||||
Our task is to choose a subset of the objects
|
Our task is to choose a subset of the objects
|
||||||
such that the sum of the weights is at most $x$
|
such that the sum of the weights is at most $W$
|
||||||
and the sum of the values is as large as possible.
|
and the sum of the values is as large as possible.
|
||||||
|
|
||||||
\begin{samepage}
|
\begin{samepage}
|
||||||
|
@ -644,26 +671,26 @@ D & 5 & 3 \\
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{samepage}
|
\end{samepage}
|
||||||
and the maximum allowed total weight is 12,
|
and $W=12$,
|
||||||
an optimal solution is to select objects $B$ and $D$.
|
an optimal solution is to select objects $B$ and $D$.
|
||||||
Their total weight $6+5=11$ does not exceed 12,
|
In this case, the sum of weights is
|
||||||
and their total value $3+3=6$ is the largest possible.
|
$6+5=11 \le 12$, and the sum of values is $3+3=6$.
|
||||||
|
|
||||||
This task can be solved in two different ways
|
This problem can be solved in two different ways
|
||||||
using dynamic programming.
|
using dynamic programming.
|
||||||
We can either regard the problem as maximizing the
|
We can either regard the problem as maximizing the
|
||||||
total value of the objects or
|
total value of the objects or
|
||||||
minimizing the total weight of the objects.
|
as minimizing the total weight of the objects.
|
||||||
|
|
||||||
\subsubsection{Solution 1}
|
\subsubsection{Solution 1}
|
||||||
|
|
||||||
\textit{Maximization:} Let $f(k,u)$
|
\textit{Maximization:} Let $\texttt{value}(k,u)$
|
||||||
denote the largest possible total value
|
denote the maximum value
|
||||||
when a subset of objects $1 \ldots k$ is selected
|
of a subset of objects $1 \ldots k$
|
||||||
such that the total weight is $u$.
|
whose weight is $u$.
|
||||||
The solution to the problem is
|
Thus, the solution to the problem is
|
||||||
the largest value
|
\[\max_{0 \le u \le W} \texttt{value}(n,u).\]
|
||||||
$f(n,u)$ where $0 \le u \le x$.
|
|
||||||
A recursive formula for calculating
|
A recursive formula for calculating
|
||||||
the function is
|
the function is
|
||||||
\[f(k,u) = \max(f(k-1,u),f(k-1,u-p_k)+a_k),\]
|
\[f(k,u) = \max(f(k-1,u),f(k-1,u-p_k)+a_k),\]
|
||||||
|
|
Loading…
Reference in New Issue