
English: 
So, the topic today is dynamic
programming.
The term programming in the
name of this term doesn't refer
to computer programming.
OK, programming is an old word
that means any tabular method
for accomplishing something.
So, you'll hear about linear
programming and dynamic
programming.
Either of those,
even though we now incorporate
those algorithms in computer
programs, originally computer
programming, you were given a
datasheet and you put one line
per line of code as a tabular

Korean: 

오늘의 주제는 동적 프로그래밍입니다. 
이 용어의 이름에서 프로그래밍이란 용어는 컴퓨터 프로그래밍을 나타내지 않습니다. 
프로그래밍은 표로 나타낸 방법을 의미하는 
오래된 단어입니다.
여러분은 선형 프로그래밍과 동적 프로그래밍에 대해 들을 것입니다. 
우리가 
컴퓨터 프로그램에서 이 알고리즘들을 
이제 포함할지라도, 
여러분은 데이터시트가 주어지고 코드 라인 당 하나의 라인을 무엇을 하는지에 대한 

Korean: 
기계 명령을 주기 위한 표의 방법으로써 주어야 합니다.
프로그래밍이라는 용어는 더 오래되었습니다. 
물론, 이제 전통적으로 여러분이 프로그래밍을 볼 때, 
여러분은 소프트웨어, 컴퓨터 프로그래밍을 의미합니다. 
그러나 그것은 항상 그 케이스가 아닙니다. 
그리고 이 용어는 문학에서 계속됩니다. 
동적 프로그래밍은 우리가 분할 정복과 같은 것에서 보았던 
다른 설계 기술들과 다른 설계 기술입니다. 
그것은 특정 알고리즘 보다는 문제의 클래스를 
푸는 방법입니다. 
우리는 소위 가장 긴 흔한 다음의 문제의 예를 위해 
이것을 통과시킬 것입니다, 

English: 
method for giving the machine
instructions as to what to do.
OK, so the term programming is
older.
Of course, and now
conventionally when you see
programming, you mean software,
computer programming.
But that wasn't always the
case.
And these terms continue in the
literature.
So, dynamic programming is a
design technique like other
design techniques we've seen
such as divided and conquer.
OK, so it's a way of solving a
class of problems rather than a
particular algorithm or
something.
So, we're going to work through
this for the example of
so-called longest common
subsequence problem,

Korean: 
때때로 LCS, OK 등으로 불립니다, 
그것은 다양한 맥락에서 나타나는 문제입니다.
그리고 그것은 계산 생물학에서 특히 중요합니다. 
거기서 여러분은 긴 DNA를 가지고, 
여러분은 두 스트링 간의 공통성을 찾으려고 합니다. 
하나는 게놈이고, 하나는 다양할 수 있습니다. 
그것은 사람들이 진화 비교를 할 때 무엇으로 불리나요? 
진화 트리, 
정확히는, 
계통 발생 트리입니다.
좋아요, 여기 문제가 있습니다. 
여러분은 두 순서가 주어졌습니다, 1에서 m까지 가는 x와 1에서 n까지 도는 y입니다. 

English: 
sometimes called LCS,
OK, which is a problem that
comes up in a variety of
contexts.
And it's particularly important
in computational biology,
where you have long DNA
strains, and you're trying to
find commonalities between two
strings, OK, one which may be a
genome, and one may be various,
when people do,
what is that thing called when
they do the evolutionary
comparisons?
The evolutionary trees,
yeah, right,
yeah, exactly,
phylogenetic trees,
there you go,
OK, phylogenetic trees.
Good, so here's the problem.
So, you're given two sequences,
x going from one to m,

Korean: 
여러분은 둘에게 공통된 가장 긴 순서를 찾고 싶습니다. 
여기서 저는 말합니다, 
그것이 가장 흔한 것에 대해 이야기하는 흔한 것일지라도요. 
보통 가장 긴 서브 시퀀스는 독특하지 않습니다. 
그것에 맞는 다른 몇 개의 서브 시퀀스가 
있을 수 있습니다. 
그런, 사람들은, 그것이 사람들이 말할 경사의 하나라고 하는 
경향이 있습니다. 저는 그것이 독특하지 않으면 말할 것입니다. 
그러나 저는 미끄러집니다 왜냐하면 많은 것이 . 
있을지라도 이야기 하는 것은 

English: 
and y running from one to n.
You want to find a longest
sequence common to both.
OK, and here I say a,
not the, although it's common
to talk about the longest common
subsequence.
Usually the longest comment
subsequence isn't unique.
There could be several
different subsequences that tie
for that.
However, people tend to,
it's one of the sloppinesses
that people will say.
I will try to say a,
unless it's unique.
But I may slip as well because
it's just such a common thing to
just talk about the,

English: 
even though there might be
multiple.
So, here's an example.
Suppose x is this sequence,
and y is this sequence.
So, what is a longest common
subsequence of those two
sequences?
See if you can just eyeball it.
AB: length two?
Anybody have one longer?
Excuse me?
BDB, BDB.

Korean: 
흔한 것이기 때문입니다
여기 예가 있습니다. x가 이 순서라고 가정해보세요, 
y는 이 순서입니다.
이 두 순서의 가장 긴 흔한 서브 시퀀스는 무엇입니까? 
여러분이 그것을 볼 수 있는지 보세요. 
AB는 길이 2인가요? 누가 하나 더 긴 것을 가지고 있나요? 
네? BDB, BDB. BDAB, 

English: 
BDAB, BDAB, BDAB,
anything longer?
So, BDAB: that's the longest
one.
Is there another one that's the
same length?
Is there another one that ties?
BCAB, BCAB, another one?
BCBA, yeah, there are a bunch
of them all of length four.
There isn't one of length five.
OK, we are actually going to
come up with an algorithm that,
if it's correct,
we're going to show it's
correct, guarantees that there
isn't one of length five.
So all those are,

Korean: 
BDAB, BDAB, 더 긴 것 있나요?
BDAB는 가장 긴 것입니다. 
같은 길이를 가진 것이 있나요? 
그것과 맞는 것이 있나요? BCAB, BCAB? 
BCBA는 길이 4의 많은 것이 있습니다.
길이 5의 것은 없습니다. 우리는 사실 알고리즘을 
찾아내려는 것입니다. 그것이 맞으면, 
우리는 그것이 맞다는 것을 보여줄 것이고 길이 5의 것이 
하나도 없다는 것을 보장합니다.

English: 
we can say, any one of these is
the longest comment subsequence
of x and y.
We tend to use it this way
using functional notation,
but it's not a function that's
really a relation.
So, we'll say something is an
LCS when really we only mean
it's an element,
if you will,
of the set of longest common
subsequences.
Once again, it's classic
abusive notation.
As long as we know what we
mean, it's OK to abuse notation.
What we can't do is misuse it.
But abuse, yeah!
Make it so it's easy to deal
with.
But you have to know what's
going on underneath.
OK, so let's see,
so there's a fairly simple
brute force algorithm for
solving this problem.
And that is,

Korean: 
이것들 중 하나는 x와 y의 가장 긴 서브 시퀀스입니다. 
우리는 함수 개념을 이용하여 이 방법을 사용하는 경향이 있지만 
그것이 관계가 아니기 때문에 함수가 아닙니다.
그것이 긴 서브 시퀀스의 집합의 인자라는 것을 의미할 때만 
그것이 LCS입니다. 
다시 한번, 
그것은 고전적인 남용의 개념입니다. 
우리가 의미하는 것을 아는 한, 남용의 개념은 괜찮습니다. 
우리가 할 수 없는 것은 그것을 잘못 사용하는 것입니다. 
남용은 다루기 쉽습니다. 
여러분은 내재된 것을 알아야 합니다. 
자 봅시다.
그래서 이 문제를 풀기 위한 간단한 알고리즘이 있습니다.
모두 검사해 봅시다, 

English: 
let's just check every,
maybe some of you did this in
your heads, subsequence of x
from one to m to see if it's
also a subsequence of y of one
to n.
So, just take every subsequence
that you can get here,
check it to see if it's in
there.
So let's analyze that.
So, to check,
so if I give you a subsequence

Korean: 
여러분 중 몇몇은 머리 속에서 이것을 했을지도 모릅니다, 
그것이 1에서 n의 y의 서브 시퀀스이면 그것은 1에서 m까지 x의 서브 시퀀스 입니다. 
여러분이 여기서 얻을 수 있는 
모든 서브 시퀀스를 가지고, 
그것이 거기 있는지 확인하세요. 
이제 분석합니다. 
제가 여러분에게 x의 서브 시퀀스를 주면, 

English: 
of x, how long does it take you
to check whether it is,
in fact, a subsequence of y?
So, I give you something like
BCAB.
How long does it take me to
check to see if it's a
subsequence of y?
Length of y,
which is order n.
And how do you do it?
Yeah, you just scan.
So as you hit the first
character that matches,
great.
Now, if you will,
recursively see whether the
suffix of your string matches
the suffix of x.
OK, and so, you are just simply
walking down the tree to see if
it matches.
You're walking down the string
to see if it matches.

Korean: 
여러분이 그것이 y의 서브 시퀀스인지 확인하는데 얼마나 걸립니까? 
저는 여러분에게 BCAB 같은 것을 줍니다. 
그것이 y의 서브 시퀀스인지 확인하는데 
얼마나 걸립니까? 
y의 길이, 그것은 오더 n입니다. 
그리고 여러분은 그것을 어떻게 하나요?
여러분은 단지 스캔합니다. 여러분이 매치되는 첫 문자를 보면, 좋습니다. 
이제 여러분이 
재귀적으로 여러분 문자의 접미사가 무엇인지 
봅니다. 
여러분은 그것이 매치되는지 보기 위해 
트리 아래로 내려갑니다. 

English: 
OK, then the second thing is,
then how many subsequences of x
are there?
Two to the n?
x just goes from one to m,
two to the m subsequences of x,
OK, two to the m.
Two to the m subsequences of x,
OK, one way to see that,
you say, well,
how many subsequences are there
of something there?
If I consider a bit vector of
length m, OK,
that's one or zero,
just every position where
there's a one,
I take out, that identifies an
element that I'm going to take
out.
OK, then that gives me a
mapping from each subsequence of
x, from each bit vector to a
different subsequence of x.
Now, of course,
you could have matching

Korean: 
그리고 두 번째는, 얼마나 많은 x의 서브 시퀀스가 있습니까? 
n에서 2입니까?
x는 1에서 m까지 갑니다, x의 서브 시퀀스는 
2에서 m입니다. 
네,
얼마나 많은 서브 시퀀스가 있습니까?
제가 길이 m의 벡터를 고려하면, 
그것은 1 또는 
0입니다, 그것은 제가 가지는 인자를 
확인합니다. 
그것은 저에게 x의 각 서브 시퀀스와의 매핑을 줍니다,  
각 비트 벡터에서 x의 다른 서브시퀀스까지요.
이제 물론, 여러분은 저기서 문자를 매칭할 수 있습니다, 

English: 
characters there,
that in the worst case,
all of the characters are
different.
OK, and so every one of those
will be a unique subsequence.
So, each bit vector of length m
corresponds to a subsequence.
That's a generally good trick
to know.
So, the worst-case running time
of this method is order n times
two to the m,
which is, since m is in the
exponent, is exponential time.
And there's a technical term
that we use when something is
exponential time.

Korean: 
최악의 케이스에서, 
모든 문자는 다릅니다.
그것들을 모두 유일한 서브 시퀀스입니다. 
길이 m의 각 비트 벡터는 서브 시퀀스와 일치합니다. 
그것은 일반적으로 알아야 하는 좋은 트릭입니다. 
이 방법의 최악의 케이스 러닝타임은 오더 n 곱하기 m의 2입니다, 
m이 지수적이기 때문에, 지수적입니다. 
그리고 지수적일 때 사용하는 기술적인 
용어가 있습니다. 

Korean: 
느리다 입니다, 좋아요. 매우 좋습니다. 
그래서 이것은 정말 나쁩니다. 
이것은 얼마나 긴 서브 시퀀스인지 만들어 내는데 
많은 시간이 걸립니다. 
그래서 우리는 이제 이 문제를 위한 효율적인 알고리즘을 
개발하는 과정을 할 것입니다. 
우리는 사실 몇 단계를 해야 합니다.
첫 번째는 단순화 단계입니다. 
우리가 하는 것은 단지 x와 y의 가장 킨 시퀀스의 
길이를 보는 것입니다. 

English: 
Slow: good.
OK, very good.
OK, slow, OK,
so this is really bad.
This is taking a long time to
crank out how long the longest
common subsequence is because
there's so many subsequences.
OK, so we're going to now go
through a process of developing
a far more efficient algorithm
for this problem.
OK, and we're actually going to
go through several stages.
The first one is to go through
simplification stage.
OK, and what we're going to do
is look at simply the length of
the longest common sequence of x
and y.

English: 
And then what we'll do is
extend the algorithm to find the
longest common subsequence
itself.
OK, so we're going to look at
the length.
So, simplify the problem,
if you will,
to just try to compute the
length.
What's nice is the length is
unique.
OK, there's only going to be
one length that's going to be
the longest.
OK, and what we'll do is just
focus on the problem of
computing the length.
And then we'll do is we can
back up from that and figure out
what actually is the subsequence
that realizes that length.
OK, and that will be a big
simplification because we don't
have to keep track of a lot of
different possibilities at every
stage.
We just have to keep track of
the one number,
which is the length.
So, it's sort of reduces it to
a numerical problem.

Korean: 
그리고 우리가 할 것은 가장 긴 서브 시퀀스를 찾기 위해  
알고리즘을 연장하는 것입니다.
우리는 길이를 볼 것입니다. 
길이를 계산하기 위해 
문제를 단순화하세요. 
좋은 것은 길이가 유일하다는 것입니다. 
가장 긴 것은 하나의 길이입니다.  
우리가 하려는 것은 길이 계산 문제에 
초점을 맞추는 것입니다.
우리가 하는 것은 그것으로부터 백업하고 길이를 깨닫는 
서브 시퀀스가 무엇인지 알아내는 것입니다.
그것은 큰 단순화입니다 왜냐하면 우리는 모든 단계에서 
많은 다양한 가능성을 쫓지 않아도 되기 때문입니다. 
우리는 하나의 수, 
길이만 쫓으면 됩니다. 
그것은 수의 문제를 줄입니다. 

Korean: 
우리는 다음 개념을 적용할 것입니다. 
그것은 표준 개념이지만, 
제가 스트링 또는 시퀀스에 절대 값을 넣으면, 
그것은 길이의 조짐을 보여줍니다. 
그것은 첫 번째 것입니다.
두 번째는, 여러분이 이와 같은 문제를 
떠올릴 때 더 많은 직관을 가져다 줄 것입니다.
어떤 면에서 
그것은 좋은 동적 프로그래밍 알고리즘 설계의 가장 어려운 부분이 될 것입니다, 
그것은 우리가 사실 모든 서브 시퀀스를 
보는 것이 아니라
접미사만 봅니다. 

English: 
We'll adopt the following
notation.
It's pretty standard notation,
but I just want,
if I put absolute values around
the string or a sequence,
it denotes the length of the
sequence, S.
OK, so that's the first thing.
The second thing we're going to
do is, actually,
we're going to,
which takes a lot more insight
when you come up with a problem
like this,
and in some sense,
ends up being the hardest part
of designing a good dynamic
programming algorithm from any
problem, which is we're going to
actually look not at all
subsequences of x and y,
but just prefixes.

English: 
OK, we're just going to look at
prefixes and we're going to show
how we can express the length of
the longest common subsequence
of prefixes in terms of each
other.
In particular,
we're going to define c of ij
to be the length,
the longest common subsequence
of the prefix of x going from
one to i, and y of going to one
to j.
And what we are going to do is
we're going to calculate c[i,j]
for all ij.

Korean: 
우리는 접미사를 볼 것이고 
우리가 서로의 관점에서 가장 긴 서브시퀀스를 
표현하는 방법을 보여줄 것입니다. 
특히 우리는 ij의 c를 길이로 정의할 것입니다, 
1에서 i까지 x의 접미사의 시퀀스, 
그리고 1에서 j까지 y입니다.
그리고 우리가 하려고 하는 것은 우리는 모든 ij를 위하여  
c[i,j]를 계산할 것입니다.

Korean: 
우리가 그것을 하면, 우리는 x와 y의 
가장 흔한 문제를 어떻게 풉니까? 
우리는 가장 긴 서브시퀀스 문제를 어떻게 풉니까? 
우리가 모든 i와 j에 대해 이것을 푼다고 가정해보세요. 
우리는 x와 y의 서브시퀀스의 길이를 어떻게 계산하나요? 
c[m,n], 
그것이 다입니다. 
n은 x와 u의 서브 시퀀스와 같습니다 
제가 1에서 n까지 가면, 다한 것이기 때문입니다. 
우리가 원하는 것은 

English: 
And if we do that,
how then do we solve the
problem of the longest common of
sequence of x and y?
How do we solve the longest
common subsequence?
Suppose we've solved this for
all I and j.
How then do we compute the
length of the longest common
subsequence of x and y?
Yeah, c[m,n],
that's all, OK?
So then, c of m,
n is just equal to the longest
common subsequence of x and y,
because if I go from one to n,
I'm done, OK?
And so, it's going to turn out
that what we want to do is

English: 
figure out how to express to
c[m,n], in general,
c[i,j], in terms of other
c[i,j].
So, let's see how we do that.
OK, so our theorem is going to
say that c[i,j] is just --

Korean: 
c[m,n]을 표현하려는 것입니다, 일반적으로는 
c[i,j]를요.
우리가 그것을 하는 방법을 봅시다. 
우리의 정리는 c[i,j]를 말합니다, 

English: 
OK, it says that if the i'th
character matches the j'th
character, then i'th character
of x matches the j'th character
of y, then c of ij is just c of
I minus one, j minus one plus
one.
And if they don't match,
then it's either going to be
the longer of c[i,
j-1], and c[i-1,
j], OK?
So that's what we're going to
prove.
And that's going to give us a
way of relating the calculation
of a given c[i,j] to values that
are strictly smaller,
OK, that is at least one of the
arguments is smaller of the two

Korean: 
, i번째 문자가 j번째 문자와 매치되면, 
x의 i번째 문자는 y의 j번째 문자와 매치됩니다. 
c[i, j]는 c[i-1, j-1] + 1입니다. 
여러분이 매치하지 않으면 
그것은 c[i, j-1], and c[i-1, j]의 
더 긴 것이 될 것입니다. 
그것이 우리가 증명해야 할 것입니다. 
그것은 우리에게 주어진 c[i,j]의 계산을 
연관시키는 방법을 줄 것입니다. 그것은 적어도 인자의 하나가 
두 인자보다 더 작다는 것입니다.

Korean: 
그리고 그것은 우리에게 c[i,j]를 계산하는 방법을 
이해할 수 있는 방법을 줍니다.
이 정리를 증명합시다. 
우리는 x[i]가 j의 y와 같은 케이스에서 출발할 것입니다. 
여기서 그림을 그려 봅시다. 
우리는 여기서 x를 가집니다. 
그리고 여기서 y를 가집니다. 

English: 
arguments.
OK, and that's going to give us
a way of being able,
then, to understand how to
calculate c[i,j].
So, let's prove this theorem.
So, we'll start with a case
x[i] equals y of j.
And so, let's draw a picture
here.
So, we have x here.
And here is y.

Korean: 
그리고 여기 제 순서 x와 y가 있습니다, 
저는 이것을 긴 박스로 그립니다, 그리고 
x[i]와 y[j]는 같습니다. 
그것이 무엇을 의미하는지 봅시다. 

English: 
OK, so here's my sequence,
x, which I'm sort of drawing as
this elongated box,
sequence y, and I'm saying that
x[i] and y[j],
those are equal.
OK, so let's see what that
means.

English: 
OK, so let's let z of one to k
be, in fact, the longest common
subsequence of x of one to i,
y of one to j,
where c of ij is equal to k.
OK, so the longest common
subsequence of x and y of one to
I and y of one to j has some
value.
Let's call it k.
And so, let's say that we have
some sequence which realizes
that.
OK, we'll call it z.
OK, so then,
can somebody tell me what z of
k is?

Korean: 
 Z[1...k]가  
LCS(x[1...i], y[1...j]) 라고 합시다.
c[i, j]가 k일때는 말이죠. x와 y의 서브시퀀스는 
같은 값을 가집니다. 
그것을 k라고 합시다. 
우리는 그것을 깨닫는 순서를 가지고 있습니다. 
그것을 z라고 합시다. 
k의 z가 무엇인지 아나요? 

English: 
What is z of k here?
Yeah, it's actually equal to x
of I, which is also equal to y
of j?
Why is that?
Why couldn't it be some other
value?
Yeah, so you got the right
idea.
So, the idea is,
suppose that the sequence
didn't include this element here
at the last element,
the longest common subsequence.
OK, so then it includes a bunch
of values in here,
and a bunch of values in here,

Korean: 
여기서 k의 z가 무엇인가요? 
그것은 사실 i의 x와 같습니다, 그것은 또한 j의 y와 같습니까? 
왜죠? 
왜 그것은 다른 값일 수 없습니까?
여러분은 옳은 생각을 가지고 있습니다. 
순서가 마지막 인자에서 
이 인자를 포함하지 않는다고 가정하세요. 
그것은 여기서 다양한 값을 
포함합니다. 그것은 이것 또는 이것을  

Korean: 
포함하지 않습니다.
그리고 저는 추가 문자를 덧붙이고 
그것을 더 크게 만들고 그것을 k+1로 만들수 있습니다. 
왜냐하면 이 둘은 매치됩니다.  
순서가 전에 끝나면, 
그것은 x[i]에 덧붙여집니다.
그것은 x[i]에 붙여진 꽤 간단한 것일 수 있습니다. 
그래서 그것이 케이스면, 

English: 
same values.
It doesn't include this or
this.
Well, then I could just tack on
this extra character and make it
be longer, make it k plus one
because these two match.
OK, so if the sequence ended
before --
-- just extend it by tacking on
x[i].
OK, it would be fairly simple
to just tack on x[i].
OK, so if that's the case,
then if I look at z going one

English: 
up to k minus one,
that's certainly a common
sequence of x of 1 up to,
excuse me, of up to i minus
one.
And, y of one up to j minus
one, OK, because this is a
longest common sequence.
z is a longest common sequence
is, from x of one to i,
y of one to j.
And, we know what the last
character is.
It's just x[i],
or equivalently,
y[j].
So therefore,
everything except the last
character must at least be a
common sequence of x of one to i
minus one, y of one to j minus
one.

Korean: 
제가 1에서 k-1까지 z를 보면, 그것은 확실히 1의 x의 흔한 순서입니다, 
미안해요, i-1까지 입니다. 
그리고 y는 1에서 j-1까지 입니다. 
왜냐하면 이것이 가장 긴 시퀀스이기 
때문입니다. 
그리고 우리는 마지막 문자가 무엇인지 압니다. 
그것은 x[i] 또는 
y[j] 입니다. 
그러므로, 마지막 문자를 
제외한 모든 것은 
적어도 1에서 i-1의 x, 1에서 j-1의 y의 순서이어야 합니다. 

English: 
Everybody with me?
It must be a comment sequence.
OK, now, what you also suspect?
What do you also suspect about
z of one to k?
It's a common sequence of these
two.
Yeah?
Yeah, it's a longest common
sequence.
So that's what we claim,
z of one up to k minus one is
in fact a longest common
subsequence of x of one to i
minus one, and y of one to j
minus one, OK?
So, let's prove that claim.
So, we'll just have a little

Korean: 
모두 알겠나요? 그것은 시퀀스여야 합니다. 
이제 여러분은 알겠나요? 1에서 k의 z에 대하여 아나요? 
그것은 이 둘의 순서입니다. 
네?
그것은 최장 공통 부분 서열입니다. 
1에서 k-1의 z는 
사실 1에서 i-1의 x, 1에서 j-1의 y의 
최장 공통 부분 서열입니다. 
그것을 증명해 봅시다. 우리는 이 주장을 증명하기 위해  

English: 
diversion to prove the claim.
OK, so suppose that w is a
longer comment sequence,
that is, that the length,
the w, is bigger than k minus
one.
OK, so suppose we have a longer
comment sequence than z of one
to k minus one.
So, it's got to have length
that's bigger than k minus one
if it's longer.
OK, and now what we do is we
use a classic argument you're
going to see multiple times,
not just this week,
which it will be important for
this week, but through several
lectures.
Hence, it's called a cut and

Korean: 
전환을 할 것입니다.
w가 최장 공통 부분 서열 보다 길다고 가정해 보세요, 
w는 k-1 보다 더 큽니다. 
우리가 1에서 k-1의 z 보다 더 긴 공통 부분 서열을 
가진다고 가정해보세요. 
그것이 더 길면 k-1 보다 다 큰 길이를 가질 겁니다. 
이제 우리는 여러분이 많은 시간을 가지고 있다는 고전적인 주장을 사용합니다, 
이번 주뿐만이 아니라
몇 강의를 통해서요. 
따라서 그것은 자르고 붙여 넣는 것입니다.

Korean: 
w를 봅시다. 
그것을 마지막 문자와 연결시키세요. 
이것은 문자열입니다. 
그래서 그것은 문자열 연속을 위한 용어입니다. 
제가 주장하는 것은 더 긴 공통 부분 서열입니다, 
저는 k의 z를 그것이라고 합니다. 
그것은 확실히 1에서 i-1의 x, 1에서 j의 y의 

English: 
paste argument.
So, the idea is let's take a
look at w, concatenate it with
that last character,
z of k.
so, this is string,
OK, so that's just my
terminology for string
concatenation.
OK, so I take whatever I
claimed was a longer comment
subsequence, and I concatenate z
of k to it.
OK, so that is certainly a

English: 
common sequence of x of one to I
minus one, and y of one to j.
And it has length bigger than k
because it's basically,
what is its length?
The length of w is bigger than
k minus one.
I add one character.
So, this combination here,
now, has length bigger that k.
OK, and that's a contradiction,
thereby proving the claim.
So, I'm simply saying,
I claim this.
Suppose you have a longer one.
Well, let me show,
if I had a longer common
sequence for the prefixes where

Korean: 
공통 부분입니다. 
그것은 k 보다 더 큰 길이를 가집니다, 
길이는 무엇입니까? w의 길이는 k-1 보다 
더 큽니다. 저는 하나의 문자를 더합니다. 
여기서 이 조합은 k 보다 큰 길이를 가집니다.
그것은 모순입니다, 그러므로 주장을 증명합시다. 
저는 이것을 주장합니다. 
여러분이 더 큰 것을 가진다고 주장하세요. 
제가 더 큰 서열을 가지면, 

Korean: 
우리는 전체의 것을 더 크게 만듭니다. 
그것을 그럴 수 없습니다. 
그러므로, 
이것은 최장 공통 부분 서열이어야 합니다. 
질문 있나요? 여러분이 지겹도록 
이런 증명을 할 필요가 있기 때문입니다.
질문이 있으면, 
하세요. 
이제 우리가 설립하려고 하는 것은 k를 통한 z-1이 
2의 최장 공통 부분 서열이라는 것입니다. 

English: 
we dropped the character from
both strings if it was longer
there, but we would have made
the whole thing longer.
So that can't be.
So, therefore,
this must be a longest common
subsequence, OK?
Questions?
Because you are going to need
to be able to do this kind of
proof ad nauseam,
almost.
So, if there any questions,
let them at me,
people.
OK, so now what we have
established is that z one
through k is a longest common
subsequence of the two prefixes

Korean: 
따라서 우리는 i-1, j-1의 c를 가집니다. 
무엇과 같나요? 
i-1, j-1의 c는 무엇이죠? 
k-1입니다 고마워요. 
ij의 c가 i-1, j-1의 c와 같다는 것을 
내포하는 계층으로 이동합시다. 
그것은 꽤 직관적입니다. 
그것이 최장 공통 부분 서열일 때 

English: 
when we drop the last character.
So, thus, we have c of i minus
one, j minus one is equal to
what?
What's c of i minus one,
j minus one?
k minus one;
thank you.
Let's move on with the class,
right, OK, which implies that c
of ij is just equal to c of I
minus one, j minus one plus one.
So, it's fairly straightforward
if you think about what's going
on there.
It's not always as

Korean: 
항상 직관적이지는 않습니다.
그래서
저는 다른 케이스를 하지 않을 것입니다. 
그것은 비슷합니다. 그러나 사실, 
우리는 동적 프로그래밍의 두 특징 중 하나를 합니다. 
특징에 의해, 
저는 여러분이 문제에서 이 구조를 볼 때를 의미합니다, 
동적 프로그래밍이 전략으로 동작하는 좋은 기회가 있습니다. 
동적 프로그래밍 특징은 
다음과 같습니다.

English: 
straightforward in some problems
as it is for longest common
subsequence.
The idea is,
so I'm not going to go through
the other cases.
They are similar.
But, in fact,
we've hit on one of the two
hallmarks of dynamic
programming.
So, by hallmarks,
I mean when you see this kind
of structure in a problem,
there's a good chance that
dynamic programming is going to
work as a strategy.
The dynamic programming
hallmark is the following.

English: 
This is number one.
And that is the property of
optimal substructure.
OK, what that says is an
optimal solution to a problem,
and by this,
we really mean problem
instance.
But it's tedious to keep saying
problem instance.
A problem is generally,
in computer science,
viewed as having an infinite
number of instances typically,
OK, so sorting is a problem.
A sorting instance is a
particular input.
OK, so we're really talking
about problem instances,
but I'm just going to say

Korean: 
이것은 수 1입니다. 그리고 그것은 최적의 서브 구조의 속성입니다, 
문제의 최적의 답은 무엇인가요, 
이것에 의해,
우리는 문제 인스턴스를 의미합니다. 
그러나 문제 인스턴스를 유지하는 것은 지루합니다..
문제는 일반적으로 무한한 수의 인스턴스를 
가지는 것으로 보여집니다, 
그래서 정렬은 문제입니다. 정렬 인스턴스는 특정한 입력입니다.
그래서 우리는 정말 문제 인스턴스에 대해 이야기할 것이지만, 
저는 문제를 말할 것입니다. 

English: 
problem, OK?
So, when you have an optimal
solution to a problem,
contains optimal solutions to
subproblems.
OK, and that's worth drawing a
box around because it's so
important.
OK, so here,
for example,
if z is a longest common
subsequence of x and y,
OK, then any prefix of z is a
longest common subsequence of a

Korean: 
여러분이 최적의 답을 
가질 때입니다. 
그것은 박스를 그릴 가지가 있습니다 
매우 중요하니까요. 
예를 들어, 
z는 x와 y의 최장 공통 부분 서열입니다.
z의 접두사는 x와 y의 

Korean: 
접두사의 최장 공통 부분 서열입니다. 
이것은 기본적으로 그것이 말하는 것입니다. 
저는 문제를 보고, 최적의 서브 구조가 
있는지 볼 수 있습니다. 이 문제에서, 
그것은 항상 여러분이 설명하는 
복사 붙여넣기가 있습니다. 
서브 구조가 최적이 아니면, 여러분은 복사 붙여넣기를 이용하여 
전체 문제의 더 나은 답을 찾을 수 있습니다.
이 정리는 
우리에게 최장 공통 부분 서열 문제를 풀 수 있는 

English: 
prefix of x, and a prefix of y,
OK?
So, this is basically what it
says.
I look at the problem,
and I can see that there is
optimal substructure going on.
OK, in this case,
and the idea is that almost
always, it means that there's a
cut and paste argument you could
do to demonstrate that,
OK, that if the substructure
were not optimal,
then you'd be able to find a
better solution to the overall
problem using cut and paste.
OK, so this theorem,
now, gives us a strategy for
being able to compute longest

English: 
comment subsequence.
Here's the code; oh wait.
OK, so going to ignore base
cases in this,
if --

Korean: 
전략을 줍니다. 
여기 코드가 있습니다, 기다리세요. 
그래서 여기에서 기본 케이스를 무시합니다. 

Korean: 
그리고 우리가 최장 공통 부분 서열의 값을 리턴할 것입니다. 

English: 
And we will return the value of
the longest common subsequence.

English: 
It's basically just
implementing this theorem.
OK, so it's either the longest
comment subsequence if they
match.
It's the longest comment
subsequence of one of the
prefixes where you drop that
character for both strengths and
add one because that's the
matching one.
Or, you drop a character from
x, and it's the longest comment
subsequence of that.
Or you drop a character from y,
whichever one of those is
longer.
That ends up being the longest
comment subsequence.
OK, so what's the worst case
for this program?
What's going to happen in the

Korean: 
그것은 기본적으로 이 정리를 구현하는 것입니다. 
그것이 매치되면 
그것은 최장 공통 부분 서열입니다. 
또는 여러분은 문자를  
떨어 트립니다, 
그것들 중 하나는 더 깁니다.
그것은 최장 공통 부분 서열으로 끝납니다.
이 프로그램의 최악의 케이스는 무엇입니까? 
최악의 케이스에서 무엇이 일어나나요? 

English: 
worst case?
Which of these two clauses is
going to cause us more headache?
The second clause:
why the second clause?
Yeah, you're doing two LCS
sub-calculations here.
Here, you're only doing one.
Not only that,
but you get to decrement both
indices, whereas here you've
basically got to,
you only get to decrement one
index, and you've got to
calculate two of them.
So that's going to generate the
tree.
So, and the worst case,
x of i is not equal to x of j
for all i and j.
So, let's draw a recursion tree
for this program to sort of get

Korean: 
이 두 절 중 어느 것이 우리에게 
두통을 유발하나요? 두 번째 절입니다. 
왜죠? 여러분은 두 LCS 서브 계산을 합니다. 
여기서 여러분은 하나만 합니다. 
그 뿐만 아니라 여러분은 양쪽을 감소합니다, 
반면에 여기서 여러분은 기본적으로 
인덱스를 감소시키고, 
여러분은 둘 중 하나를 계산할 것입니다. 
그래서 그것은 트리를 생성할 것입니다.
i의 x는 모든 i와 j에 대하여 j의 x와 같지 않습니다. 
우리를 돕는 것이 무엇인지에 대한 이해를 얻기 위해 

English: 
an understanding as to what is
going on to help us.
And, I'm going to do it with m
equals seven,
and n equals six.
OK, so we start up the top with
my two indices being seven and
six.
And then, in the worst case,
we had to execute these.
So, this is going to end up
being six, six,
and seven, five for indices
after the first call.
And then, this guy is going to
split.
And he's going to produce five,
six here, decrement the first
index, I.
And then, if I keep going down
here, we're going to get four,
six and five,
five.
And these guys keep extending
here.
I get six five,

Korean: 
이 프로그램을 위한 재귀 트리를 그립시다. 
m은 7이고, 
n은 6입니다. 
우리는 위에서 시작합니다. 
최악의 케이스에서, 우리는 이것을 실행해야 합니다. 
이것은 첫 번째 호출 후에 
6 6 7 6에서 끝납니다.
이것은 쪼갤 것입니다. 
그는 여기서 5 6을 생산할 것입니다, 첫 인덱스 i를 감소시킵니다. 
그리고 제가 여기서 계속 하면, 
우리는 4 6 5 5 를 얻습니다. 
이것들은 여기서 계속 연장합니다. 
저는 6 5 

English: 
five five, six four,
OK?
Over here, I'm going to get
decrement the first index,
six five, and I get five five,
six four, and these guys keep
going down.
And over here,
I get seven four.
And then we get six four,
seven three,
and those keep going down.
So, we keep just building this
tree out.
OK, so what's the height of
this tree?
Not of this one for the
particular value of m and n,
but in terms of m and n.
What's the height of this tree?

Korean: 
5 5 6 4를 얻습니다. 
여기서 저는 첫 인덱스 6 5를 감소시키고, 
5 5 6 4를 얻고 이것들은 아래로 내려갑니다. 
여기서 
저는 7 4를 얻습니다. 그리고 우리는 6 4 
7 3을 얻고 아래로 내려갑니다. 
우리는 이 트리를 계속 구축합니다.
이 트리의 높이는 무엇이죠? 
이것은 특정한 값 m n을 위한 것이 아니지만, 
m과 n의 관점에서입니다. 이 트리의 높이는 무엇이죠? 

English: 
It's the max of m and n.
You've got the right,
it's theta of the max.
It's not the max.
Max would be,
in this case,
you're saying it has height
seven.
But, I think you can sort of
see, for example,
along a path like this that,
in fact, I've only,
after going three levels,
reduced m plus n,
good, very good,
m plus n.
So, height here is m plus n.
OK, and its binary.
So, the height:
that implies the work is
exponential in m and n.
All that work,

Korean: 
그것은 m과 n의 최대입니다. 여러분은 옳습니다. 
그것은 최대값의 세타입니다. 그것은 최대값이 아닙니다. 
이 케이스에서, 
여러분은 그것이 높이 7을 가진다고 말합니다.
제 생각에 
여러분은 이와 같은 길을 때, 
3 단계 후에, 
m + n을 줄입니다. 
여기서 높이는 m + n입니다. 그것은 이진입니다. 
작업을 내포하는 높이는 m과 n에서 
지수적입니다. 

English: 
and are we any better off than
the brute force algorithm?
Not really.
And, our technical term for
this is slow.
OK, and we like speed.
OK, we like fast.
OK, but I'm sure that some of
you have observed something
interesting about this tree.
Yeah, there's a lot of repeated
work here.
Right, there's a lot of
repeated work.
In particular,
this whole subtree,
and this whole subtree,
OK, they are the same.
That's the same subtree,
the same subproblem that you
are solving.
OK, you can even see over here,
there is even similarity
between this whole subtree and

Korean: 
알고리즘을 강요하는 것 보다 더 나은가요? 
그렇지 않습니다. 이를 위한 우리의 기술적 용어는 slow입니다. 
그리고 우리는 속도를 좋아합니다. 
우리는 빠른 것을 좋아합니다. 그러나 여러분은 
이 트리에 대한 흥미로운 것을 보았을 겁니다. 
여기서 많은 반복 작업이 이루어집니다. 
많은 반복 작업이 있습니다.
특히, 이 전체 서브 트리와 
이 전체 서브 트리는 같습니다.  
그것은 같은 서브 트리이고 여러분이 푸는 같은 서브 문제입니다.
여러분은 여기서 볼 수 있습니다. 
이 전체 서브 트리와 이 전체 스브 트리 사이의 유사성이 있습니다. 

Korean: 
많은 반복 작업이 이루어집니다. 
여러분이 빠르게 하고 싶으면, 
같은 것을 하지 마세요. 
같은 것을 하지 마세요. 
여러분이 반복되는 것을 찾을 때, 
그것을 하지 않는 방법을 알아 내세요. 
그것은 동적 프로그래밍을 위한 두 번째 특징을 
가져옵니다.

English: 
this whole subtree.
OK, so there's lots of repeated
work.
OK, and one thing is,
if you want to do things fast,
don't keep doing the same
thing.
OK, don't keep doing the same
thing.
When you find you are repeating
something, figure out a way of
not doing it.
So, that brings up our second
hallmark for dynamic
programming.

English: 
And that's a property called
overlapping subproblems,
OK?
OK, recursive solution contains
many, excuse me,
contains a small number of
distinct subproblems repeated
many times.
And once again,
this is important enough to put
a box around.
I don't put boxes around too

Korean: 
그것은 서브 문제를 오버래핑하는 속성입니다. 
재귀적 해결은 
개별적인 서브 문제들의 수를 
포함합니다. 
이것은 박스에 집어 넣을 만큼 중요합니다. 
저는 박스에 많은 것을 넣지 않습니다. 

Korean: 
저는 박스에 넣어야 합니다. 
이것은 분명히 박스에 넣어야 합니다. 
예를 들어, 
여기서 우리는 재귀 문제를 가집니다. 
이 트리는 크기에서 지수적입니다. 
그것은 m의 2 더하기 n입니다, 
높이에서, 사이즈에서, 문제 총 수에서요, 제가 그것을 구현한다면요. 
그러나 얼마나 많은 서브 문제들이 있습니까?
m 곱하기 n 입니다.  
서브 문제들은 
m 곱하기 n을 보유합니다. 그리고

English: 
many things.
Maybe I should put our boxes
around things.
This is definitely one to put a
box around, OK?
So, for example,
so here we have a recursive
solution.
This tree is exponential in
size.
It's two to the m plus n in
height, in size,
in the total number of problems
if I actually implemented like
that.
But how many distinct
subproblems are there?
m times n, OK?
So, the longest comment
subsequence, the subproblem
space contains m times n,
distinct subproblems.

Korean: 
이것은 m의 2 더하기 n과 
비교되는 작은 수 입니다. 
이것은 작습니다
각 서브 문제를 위하여, 
그것은 i와 j에 의해 특징 지어지기 때문입니다. 
i는 1에서 m까지 가고, j는 1에서 n까지 갑니다. 
많은 서브 문제들이 있지 않습니다.
그것은 2의 곱입니다. 
여기 향상된 알고리즘이 있습니다, 그것은 종종 그것을 푸는 좋은 방법입니다. 
그것은 memo-ization라는 
알고리즘입니다. 

English: 
OK, and then this is a small
number compared with two to the
m plus n, or two to the n,
or two to the m,
or whatever.
OK, this is small,
OK, because for each
subproblem, it's characterized
by an I and a j.
An I goes from one to m,
and j goes from one to n,
OK?
There aren't that many
different subproblems.
It's just the product of the
two.
So, here's an improved
algorithm, which is often a good
way to solve it.
It's an algorithm called a
memo-ization algorithm.

Korean: 
이것은 memo-ization 입니다, memorization이 아닙니다 
여러분이 하려는 것은 서브 문제를 풀 때 마다 작은 메모를 하는 것이기 때문입니다. 
저는 이것을 이미 풀었습니다. 
그리고 여러분이 그것을 다시 계산하기 보다 그것을 물었다면, 
저는 그것을 봅니다. 저는 전에 했습니다. 
여기 답이 있습니다. 
여기 코드가 있습니다. 
그것은 그 코드와 매우 비슷합니다.
그것은 c[i,j] 주위의 테이블을 기본적으로 유지합니다. 우리가 하는 것은 검사입니다. 
. c[i,j]를 위한 엔트리가 nil이면, 우리는 그것을 계산하지 않았습니다, 
그러면 그것을 계산합니다. 
어떻게 그것을 계산하나요? 

English: 
And, this is memo-ization,
not memorization because what
you're going to do is make a
little memo whenever you solve a
subproblem.
Make a little memo that says I
solved this already.
And if ever you are asked for
it rather than recalculating it,
say, oh, I see that.
I did that before.
Here's the answer,
OK?
So, here's the code.
It's very similar to that code.
So, it basically keeps a table
around of c[i,j].
It says, what we do is we
check.
If the entry for c[i,j] is nil,
we haven't computed it,
then we compute it.
And, how do we compute it?
Just the same way we did
before.

Korean: 
우리가 전에 했던 것과 같은 방법입니다. 여기 이 전체 부분은 우리가 전에 했던 것과 같은 것입니다. 
그것은 전과 같습니다. 
우리는 c[i,j]를 리턴합니다. 

English: 
OK, so this whole part here,
OK, is exactly what we have had
before.
It's the same as before.
And then, we just return
c[i,j].

Korean: 
우리가 다시 계산 하지 않으면, 그것이 nil이면, 
그것을 계산합니다. 
그렇지 않으면, 그것을 리턴합니다. 그것은 계산되지 않았고, 계산한 뒤 그것을 리턴합니다. 
그렇지 않으면, 그냥 리턴합니다. 
매우 직관적인 코드입니다.
좋아요.
이제 까다로운 것은 이것을 수행하는데 시간이 얼마나 
걸립니까? 

English: 
If we don't bother to keep
recalculating,
OK, so if it's nil,
we calculate it.
Otherwise, we just return it.
It's not calculated,
calculate and return it.
Otherwise, just return it:
OK, pretty straightforward
code.
OK.
OK, now the tricky thing is how
much time does it take to
execute this?

English: 
This takes a little bit of
thinking.
Yeah?
Yeah, it takes order MN.
OK, why is that?
Yeah, but I have to look up
c[i,j].
I might call c[i,j] a bunch of
times.
When I'm doing this,
I'm still calling it
recursively.
Yeah, so you have to,
so each recursive call is going
to look at, and the worst-case,
say, is going to look at the
max of these two things.
Well, this is going to involve

Korean: 
이것은 생각하는데 약간 걸립니다. 
네, 그것은 오더 MN이 걸립니다. 
왜 그렇죠? 그러나 저는 c[i,j]를 찾아야 합니다. 
저는 c[i,j]를 많은 시간으로 부릅니다. 
제가 이것을 할 때, 
저는 그것을 재귀적으로 호출합니다. 
각 재귀 호출은 볼 것이고, 최악의 케이스는 
이 둘의 최대값을 볼 것입니다. 
이것은 재귀 호출을 

Korean: 
포함합니다.
이것은 계산하는데 꽤 많은 노력이 듭니다. 
여러분은 맞습니다, 여러분의 직관은 맞습니다. 
우리나 더 정확한 의견을 가질 수 있는지 봅시다, 
이것은 왜 오더 m 곱하기 n인가요?
그것은 여기서 무엇이 되나요? 매번 제가 이것을 호출하지 않는 것은 
이것을 하는데 정수의 작업이 걸립니다. 
때때로 그것은 많은 일이 걸립니다. 
때때로 저는 운이 좋고, 그것을 리턴합니다.
여러분의 직관은 죽었습니다. 
그것은 죽었습니다. 우리는 단지 
분명한 설명이 필요합니다. 

English: 
a recursive call,
and a lookup.
So, this might take a fair
amount of effort to calculate.
I mean, you're right,
and your intuition is right.
Let's see if we can get a more
precise argument,
why this is taking order m
times n.
What's going on here?
Because not every time I call
this is it going to just take me
a constant amount of work to do
this.
Sometimes it's going to take me
a lot of work.
Sometimes I get lucky,
and I return it.
So, your intuition is dead on.
It's dead on.
We just need a little bit more
articulate explanation,
so that everybody is on board.

English: 
Try again?
Good, at most three times,
yeah.
OK, so that's one way to look
at it.
Yeah.
There is another way to look at
it that's kind of what you are
expressing there is an
amortized, a bookkeeping,
way of looking at this.
What's the amortized cost?
You could say what the
amortized cost of calculating
one of these,
where basically whenever I call
it, I'm going to charge a
constant amount for looking up.
And so, I could get to look up
whatever is in here to call the
things.
But if it, in fact,
so in some sense,
this charge here,
of calling it and returning it,
etc., I charged that to my
caller.
OK, so I charged these lines
and this line to the caller.
And I charge the rest of these
lines to the c[i,j] element.
And then, the point is that

Korean: 
다시 해볼까요? 적어도 3번을요. 
그것은 그것을 보는 하나의 방법입니다. 
네.
그것을 보는 또 다른 방법이 있습니다 
여러분이 표현하는 것은 분할 상환, 이것을 보는 방법입니다. 
분할 상환 비용은 무엇이죠?
여러분은 이것들 중 하나를 계산하는 비용이 무엇인지 말할 수 있고, 
제가 호출할 때 마다, 
저는 찾기 위한 정수의 양을 청구합니다. 
저는 호출하기 위해 여기 무엇이 있는지 찾을 수 있습니다.
그러나 사실, 
어떤 면에서, 이것은 여기서 청구합니다, 
그것을 리턴하고 호출하는 데서요. 저는 이 라인과 이 라인을 
호출자에게 청구합니다. 
그리고 나머지 라인을 c[i,j] 인자에 청구합니다. 
그리고 핵심은  

Korean: 
모든 호출자가 기본적으로 정수 양을 위해 청구되는 데서 마칩니다.
c[i,j]를 청구하기 위해, 
그것은 제가 i와 j의 계산을 청구하는 
분할 상환 정수 양입니다. 
그래서 여러분은 
분할 상환 분석의 관점에서 그것을 볼 수 있습니다. 
계산하기 충분하게 청구하겠습니다. 
다음 단계에서 값을 찾기 충분하고 
그것을 리턴합니다.
그리고 그것이 가서 계산하면, 그것은 괜찮습니다 
왜냐하면 그것은 그 점에서 다른 ij로 바뀌기 때문입니다. 
모든 세포는 오더 MN의 
정수 시간이 듭니다. 

English: 
every caller basically only ends
up being charged for a constant
amount of stuff.
OK, to calculate one c[i,j],
it's only an amortized constant
amount of stuff that I'm
charging to that calculation of
i and j, that calculation of i
and j.
OK, so you can view it in terms
of amortized analysis doing a
bookkeeping argument that just
says, let me charge enough to
calculate my own,
do all my own local things plus
enough to look up the value in
the next level and get it
returned.
OK, and then if it has to go
off and calculate,
well, that's OK because that's
all been charged to a different
ij at that point.
So, every cell only costs me a
constant amount of time that
order MN cells total of order

English: 
MN.
OK: constant work per entry.
OK, and you can sort of use an
amortized analysis to argue
that.
How much space does it take?
We haven't usually looked at
space, but here we are going to
start looking at space.
That turns out,
for some of these algorithms,
to be really important.
How much space do I need,
storage space?
Yeah, also m times n,
OK, to store the c[i,j] table.
OK, the rest,
storing x and y,
OK, that's just m plus n.
So, that's negligible,
but mostly I need the space m
times n.
So, this memo-ization type
algorithm is a really good
strategy in programming for many
things where,
when you have the same
parameters, you're going to get
the same results.
It doesn't work in programs
where you have a side effect,
necessarily,
that is, when the calculation
for a given set of parameters

Korean: 
엔트리당 정수 작업입니다. 
여러분은 그것을 주장하기 위해 분할 상환 분석을 사용할 수 있습니다. 
그것은 얼마나 많은 공간이 드나요? 
우리는 공간을 보지 못했지만 
여기서 공간을 보기 시작합니다. 
이 알고리즘의 몇 개를 위하여, 그것은 정말 중요할 것입니다. 
저는 저장 공간으로 얼마나 필요하나요?
c[i,j] 테이블에 저장하기 위하여 M 곱하기 n입니다. 
X와 y를 저장하는 것은 
m 더하기 n입니다.
그것은 무시해도 될 정도이지만 보통 저는 m 곱하기 n의 공간이 필요합니다. 
이 memo-ization 타입 알고리즘은 
정말 좋은 전략입니다 
여러분이 같은 파라미터를 가질 때, 
여러분은 같은 결과를 얻습니다. 
즉, 주어진 파라미터 집합의 계산이 
각 호출에서 다를 때입니다.

Korean: 
그러나 그것은 특히 
기능적인 프로그래밍 타입과 같습니다. 
여러분이 그것을 한번 계산하면, 여러분은 그것을 찾을 수 있습니다. 
이것은 매우 도움이 됩니다. 그것은 꽤 많은 공간이 듭니다, 
그리고 그것은 매우 정렬된 방법으로 나아가지 않습니다. .
아래에서 위의 방식에서 정확히 같은 계산을 하기 위한 
또 다른 전략이 있습니다. 그리고 그것은 동적 프로그래밍입니다.
아이디어는 테이블을 계산하는 것입니다. 
저는 우리가 하는 것이, 
이 보드를 

English: 
might be different on each call.
But for something which is
essentially like a functional
programming type of environment,
then if you've calculated it
once, you can look it up.
And, so this is very helpful.
But, it takes a fair amount of
space, and it also doesn't
proceed in a very orderly way.
So, there is another strategy
for doing exactly the same
calculation in a bottom-up way.
And that's what we call dynamic
programming.
OK, the idea is to compute the
table bottom-up.
I think I'm going to get rid
of, I think what we'll do is
we'll just use,

English: 
actually I think what I'm going
to do is use this board.
OK, so here's the idea.
What we're going to do is look
at the c[i,j] table and realize
that there's actually an orderly
way of filling in the table.
This is sort of a top-down with
memo-ization.
OK, but there's actually a way

Korean: 
사용하는 것이라고 생각해요. 
여기 생각이 있습니다. 
우리가 하려고 하는 것은 c[i,j] 테이블을 보고 테이블에서 정렬된 방법이 있다는 것을 깨닫는 것입니다. 
이것은 상의하달식입니다. 
그러나 사실 우리가 그것을 거꾸로 하는 방법이 있습니다. 

English: 
we can do it bottom up.
So, here's the idea.
So, let's make our table.
OK, so there's x.
And then, there's y.
And, I'm going to initialize
the empty string.
I didn't cover the base cases
for c[i,j], but c of zero
meaning a prefix with no
elements in it.
The prefix of that with
anything else,
the length is zero.
OK, so that's basically how I'm
going to bound the borders here.
And now, what I can do is just
use my formula,

Korean: 
우리의 테이블을 만들어 봅시다.
X가 있습니다. 
그리고 y가 있습니다. 저는 빈 문자열을 초기화할 것입니다. 
저는 c[i,j]를 위한 기본 케이스를 다루지 않지만, 
0의 c는 그 안에 인자가 없는 접두사를 의미합니다.
그것의 접두사는, 
길이가 0입니다. 
그것은 기본적으로 제가 여기서 경계를 바운드하는 방법입니다. 
이제 제가할 수 있는 것은 제 공식을 사용하는 것입니다,

Korean: 
그것은 통상적으로 저기서 지워집니다. 
최장 공통 부분 서열을 
계산하기 위해, 
y와 x에 문자가 있습니다.
예를 들어, 그것들은 매치되지 않습니다. 
그것은 이 두 값의 최대값입니다. 
여기서, 그것들은 매치합니다. 그래서 그것은 1 더하기 값입니다.
저는 선을 그릴 것입니다. 
제가 매치할 때 마다, 저는 이와 같은 선을 나타낼 것입니다, 
그것은 제가 첫 번째 케이스를 가진다는 것을 나타냅니다, 
그것은 좋은 매치를 가집니다. 
제가 하는 모든 것은 우리가 증명한 정리로부터 재귀 공식을 적용하는 것입니다. 
그것은 기본적으로 매치하지 않습니다. 
그것은 이 둘의 최대값입니다. 
여기서, 그것들은 매치합니다. 

English: 
which I've conveniently erased
up there, OK,
to compute what is the longest
common subsequence,
length of the longest comment
subsequence from this character
in y, and this character in x up
to this character.
So here, for example,
they don't match.
So, it's the maximum of these
two values.
Here, they do match.
OK, so it says it's one plus
the value here.
And, I'm going to draw a line.
Whenever I'm going to get a
match, I'm going to draw a line
like that, indicating that I had
that first case,
the case where they had a good
match.
And so, all I'm doing is
applying that recursive formula
from the theorem that we proved.
So here, it's basically they
don't match.
So, it's the maximum of those
two.
Here, they match.

Korean: 
그것은 1 더하기 그것입니다. 여기서 그것들은 매치하지 않습니다.
기본적으로 그것은 이 둘의 최대값입니다. 
그것들은 매치하지 않습니다. 그것은 최대값입니다.
그것은 1 더하기 그것입니다. 모두 제가 어떻게 첫 번째 줄을 채우는지 이해했나요? 
자 여러분은 도울 수 있습니다. 
그래서 이것은 무엇인가요? 
호출해보세요. 0입니다, 좋아요. 
1입니다, 왜냐하면 그것이 최대값이기 때문입니다. 
이 1은 저기  
2 2 로부터 왔습니다.

English: 
So, it's one plus that guy.
Here, they don't match.
So, it's basically the maximum
of these two.
Here, they don't match.
So it's the maximum.
So, it's one plus that guy.
So, everybody understand how I
filled out that first row?
OK, well that you guys can
help.
OK, so this one is what?
Just call it out.
Zero, good.
One, because it's the maximum,
one, two, right.
This one, now,
gets from there,
two, two.
OK, here, zero,

English: 
one, because it's the maximum
of those two.
Two, two, two,
good.
One, one, two,
two, two, three,
three.
One, two, three,

Korean: 
그것은 이 둘의 최대값이기 때문입니다.
2 2 2입니다. 
1 1 2 2 2 3 3.  
1 2 3, 

English: 
get that line,
three, four,
OK.
One there, three,
three, four,
good, four.
OK, and our answer:
four.
So this is blindingly fast code
if you code this up,
OK, because it gets to use the
fact that modern machines in
particular do very well on
regular strides through memory.
So, if you're just plowing
through memory across like this,
OK, and your two-dimensional
array is stored in that order,
which it is,
otherwise you go this way,

Korean: 
선이 있고, 3 4. 
1 3 
3 4 4. 
그리고 우리의 답은 4입니다.
이것은 매우 빠른 코드입니다 
그것은 현대 기계가 잘 동작한다는 
사실을 사용하기 때문입니다. 
여러분이 이와 같은 기억으로 나아가면, 
여러분의 2차원 배열은 그 순서로 저장됩니다, 
그렇지 않으면 여러분은 길로 가서, 그 순서로 저장됩니다.

English: 
stored in that order.
This can really fly in terms of
the speed of the calculation.
So, how much time did it take
us to do this?
Yeah, order MN,
theta MN.
Yeah?
We'll talk about space in just
a minute.
OK, so hold that question.
Good question,
good question,
already, wow,
good, OK, how do I now figure
out, remember,
we had the simplification.
We were going to just calculate
the length.
OK, it turns out I can now
figure out a particular sequence
that matches it.
And basically,
I do that.

Korean: 
이것은 계산의 속도의 관점에서 정말 날 수 있습니다.
우리가 그것을 하는데 시간이 얼마나 걸렸나요? 
order MN, 
theta MN 입니다. 
우리는 곧 공간에 대해 이야기할 것입니다. 
그러니 질문을 가지고 있으세요. 
좋은 질문입니다. 
우리가 단순화를 가지는 것을 어떻게 알아내나요? 
우리는 길이를 계산했습니다. 
제가 그것과 매치되는 특정한 순서를 
알아낼 수 있습니다. 
기본적으로, 저는 그것을 합니다.

Korean: 
저는 뒤로 가면서 최장 공통 부분 서열을 다시 구축할 수 있습니다. 
필수적으로 저는 여기서 시작합니다. 
여기서 저는 제 선택을 가지고 있습니다 왜냐하면 이것은 의존적이기 때문입니다, 
그것이 여기서 –를 가지고 있지 않으면, 그것은 이 둘 중 하나에 의존적입니다. 
이 길로 갑시다. 
이제 저는 대각선의 인자를 가집니다. 
우리가 할 것은 단지 그 위치에 나타난 문자에 
표기하는 것입니다. 
저는 여기서 3을 가집니다. 계속 하겠습니다, 
여기 3이 있고, 저는 이제 다른 1을 가집니다. 

English: 
I can reconstruct the longest
common subsequence by tracing
backwards.
So essentially I start here.
Here I have a choice because
this one was dependent on,
since it doesn't have a bar
here, it was dependent on one of
these two.
So, let me go this way.
OK, and now I have a diagonal
element here.
So what I'll do is simply mark
the character that appeared in
those positions as I go this
way.
I have three here.
And now, let me keep going,
three here, and now I have
another one.

Korean: 
그것은 이 문자가 선택되는 것을 의미합니다.
그리고 저는 여기로 갑니다. 그리고 나서 여기로 갑니다. 
이제 저는 다시 대각선으로 갑니다, 그것은 이 문자가 선택된다는 것을 의미합니다. 
저는 여기로 가고, 
그리고 나서 여기로 갑니다. 저는 여기로 올라가서 이 문자가 선택됩니다. 
여기 제 최장 공통 부분 서열이 있습니다. 
이것은 하나의 경로입니다. 
저는 이와 같은 경로로 갈 수 있고  
다른 최장 공통 부분 서열을 가질 수 있습니다.
뒤로 가서 
그것을 알아내 봅시다. 
그것은 사실 좋은 것입니다 
왜냐하면 그것은 값을 계산함으로써, 이것들을 알아내는 것이기 때문입니다. 

English: 
So that means this character
gets selected.
And then I go up to here,
OK, and then up to here.
And now I go diagonally again,
which means that this character
is selected.
And I go to here,
and then I go here.
And then, I go up here and this
character is selected.
So here is my longest common
subsequence.
And this was just one path
back.
I could have gone a path like
this and gotten a different
longest common subsequence.
OK, so that simplification of
just saying, look,
let me just run backwards and
figure it out,
that's actually pretty good
because it means that by just
calculating the value,
then figuring out these back

Korean: 
저는 간단한 과정으로 재 구축하겠습니다.
제가 그것에 대해 생각하면, 
그것은 더 많이 엉망입니다. 
공간은 오더 MN 입니다 왜냐하면 
우리는 여전히 테이블이 필요하기 때문입니다.
여러분은 사실 m과 n의 최소를 할 수 있습니다. 
여러분은 m과 n의 최소를 어떻게 얻습니까? 
대각선은 여러분에게 m과 n의 최소를 주지 않을 것입니다. 
그것은 여러분에게 m과 n의 합을 줄 것입니다. 
아마 저는 여러분이 의미하는 것을 
확신하지 않습니다. 
제가 여기서 하는 순서는 무엇입니까?

English: 
pointers to let me reconstruct
it is a fairly simple process.
OK, if I had to think about
that to begin with,
it would have been a much
bigger mess.
OK, so the space,
I just mentioned,
was order MN because we still
need the table.
So, you can actually do the min
of m and n.
OK, to get to your question,
how do you do the min of m and
n?
Diagonal stripes won't give you
min of m and n.
That'll give you the sum of m
and n.
So, going in stripes,
maybe I'm not quite sure I know
what you mean.
So, you're saying,
so what's the order I would do

English: 
here?
So, I would start.
I would do this one first.
Then which one would I do?
This one and this one?
And then, this one,
this one, this one,
like this?
That's a perfectly good order.
OK, and so you're saying,
then, so I'm keeping the
diagonal there all the time.
So, you're saying the length of
the diagonal is the min of m and
n?
I think that's right.
OK, there is another way you
can do it that's a little bit
more straightforward,
which is you compare m to n.
Whichever is smaller,
well, first of all,
let's just do this existing
algorithm.
If I just simply did row by
row, I don't need more than a
previous row.
OK, I just need one row at a
time.
So, I can go ahead and compute

Korean: 
저는 시작합니다, 
저는 먼저 1을 시작합니다. 그리고 저는 무엇을 합니까? 
이것과 이것인가요? 
그리고 이것들 입니까? 
그것은 완벽하게 좋은 순서입니다. 
그리고 여러분은, 항상 대각선을 유지합니다. 
여러분은 대각선의 길이가 m과 n의 최소값이라고 
말할 수 있습니까? 
여러분이 그것을 더 직관적으로 할 수 있는 다른 방법이 있습니다, 
그것은 m과 n을 비교하는 것입니다. 
먼저, 이 존재하는 
알고리즘을 합시다. 
제가 그것을 열 대로 하면, 저는 이전의 열 이상이 필요하지 않습니다. 
저는 한 번에 하나의 열이 필요합니다. 
저는 미리 가서 하나의 열을 계산할 수 있습니다 

English: 
just one row because once I
computed the succeeding row,
the first row is unimportant.
And in fact,
I don't even need the whole
row.
All I need is just the current
row that I'm on,
plus one or two elements of the
previous row,
plus the end of the previous
row.
So, I use a prefix of this row,
and an extra two elements,
and the suffix of this row.
So, it's actually,
you can do it with one row,
plus order one element.
And then, I could do it either
running vertically or running
horizontally,
whichever one gives me the
smaller space.
OK, and it might be that your
diagonal trick would work there
too.
I'd have to think about that.
Yeah?
Ooh, that's a good question.
So, you can do the calculation
of the length,
and run row plus order one
elements.
OK, and our exercise,

Korean: 
왜냐하면 제가 연속되는 열을 계산하면, 첫 번째 열은 중요하지 않기 때문입니다. 
사실, 저는 
전체 열이 필요하지 않습니다. 
제가 필요한 모든 것은 현재 열입니다. 
더하기 이전 열의 하나 또는 두 인자, 
더하기 이전 열의 마지막 인자입니다. 
저는 이 열의 접두사, 
남은 두 인자, 그리고 이 열의 
접미사를 사용합니다. 
그리고 저는 이것을 수직으로 또는 수평으로 돌릴 수 있습니다, 
그것은 저에게 더 작은 공간을 줍니다.
그리고 대각선 트릭은 거기서 
작동할 것입니다. 
저는 그것에 대해 생각해 보아야 합니다. 
그것은 좋은 질문입니다. 
여러분은 길이 계산을 할 수 있습니다.
우리의 문제는 어렵습니다. 

English: 
and this is a hard exercise,
OK, so that a good one to do is
to do small space and allow you
to reconstruct the LCS because
the naÔve way that we were just
doing it, it's not clear how you
would go backwards from that
because you've lost the
information.
OK, so this is actually a very
interesting and tricky problem.
And, it turns out it succumbs
of all things to divide and
conquer, OK, rather than some
more straightforward tabular
thing.
OK: so very good practice,
for example,
for the upcoming take home
quiz, OK, which is all design

Korean: 
좋은 것은 작은 공간을 하는 것이고 여러분에게 LCS를 
재 구축하도록 하는 것입니다. 
여러분이 그것으로부터 하는 방법은 분명하지 않습니다 
왜냐하면 여러분은 정보를 잃었기 때문입니다. 
그래서 이것은 사실 매우 흥미롭고 까다로운 문제입니다.
그리고 그것은 분할 정복의 모든 것에 굴복합니다. 
더 직관적인 표의 것  
보다는요.
매우 좋은 연습입니다. 예를 들어, 
다가오는 퀴즈는 모두 설계 그리고 현명한 타입의 퀴즈입니다. 

English: 
and cleverness type quiz.
OK, so this is a good one for
people to take on.
So, this is basically the
tabular method that's called
dynamic programming.
OK, memo-ization is not dynamic
programming, even though it's
related.
It's memo-ization.
And, we're going to see a whole
bunch of other problems that
succumb to dynamic programming
approaches.
It's a very cool method,
and on the homework,
so let me just mention the
homework again.
On the homework,
we're going to look at a
problem called the edit distance
problem.
Edit distance is you are given
two strings.
And you can imagine that you're
typing in a keyboard with one of
the strings there.
And what you have to do is by
doing inserts,
and deletes,
and replaces,
and moving the cursor around,
you've got to transform one
string to the next.
And, each of those operations
has a cost.

Korean: 
이것은 수강하는 학생들에게 좋습니다. 
이것은 기본적으로 
동적 프로그래밍이라는 표의 방법입니다. 
memo-ization은 동적 프로그래밍이 아닙니다, 그것이 연관되었다 하더라도요. 
그것은 memo-ization 입니다. 
그리고 우리는 동적 프로그래밍 접근에 굴복하는 
다른 많은 문제를 볼 것입니다. 
그것은 매우 좋은 방법이고, 
여러분에게 다시 숙제에 대해 언급하겠습니다.
숙제에서, 우리는 
길이 문제 수정이라는 문제를 볼 것입니다. 
길이 수정은 주어진 두 문자열이 있습니다. 
여러분은 문자열 중 하나를 키보드로 타이핑 한다고 상상할 수 있습니다. 
여러분이 해야 하는 것은 
삽입, 삭제, 
교체, 커서 움직이기를 함으로써, 
하나의 문자열을 다음으로 변환시킵니다. 
각 연산은 비용이 듭니다. 

English: 
And your job is to minimize the
cost of transforming the one
string into the other.
This actually turns out also to
be useful for computational
biology applications.
And, in fact,
there have been editors,
screen editors,
text editors,
that implement algorithms of
this nature in order to minimize
the number of characters that
have to be sent as IO in and out
of the system.
So, the warning is,
you better get going on your
programming on problem one on
the homework today if at all
possible because whenever I
assign programming,
since we don't do that as sort
of a routine thing,
I'm just concerned for some
people that there will not be
able to get things like the
input and output to work,
and so forth.
We have example problems,
and such, on the website.

Korean: 
여러분의 일은 하나의 문자열을 다른 것으로 변환하는 비용을 최소화하는 것입니다.
이것은 사실 
계산 생물학 응용에 유용합니다.
 IO와 시스템 밖으로 전달되는 
문자열의 수를 최소화하기 위해 
이 자연의 알고리즘을 구현하는 
편집자, 스크린 편집자, 
텍스트 편집자들이 있습니다. 
여러분은 오늘 숙제에서 많은 문제를 더 낫게 할 것입니다 
왜냐하면 제가 프로그래밍을 할당할 때 마다, 
우리는 그것을 
정기적인 것으로 하지 않습니다, 
저는 입력 출력 등과 같은 것을 할 수 있는 것에 
관심이 있습니다. 
웹사이트에 예제 문제가 있습니다. 

Korean: 
여러분은 
Matlab, Python을 포함한 
어떤 언어든 여러분이 원하는 것으로 쓸 수 있습니다.
가장 빠른 답은 c로 쓰는 것입니다. 
여러분은 그것을 어셈블리 언어로 
할 수도 있습니다. 
저는 과거에 어셈블리 
언어 프로그래머였습니다. 
저는 여러분이 이것을 
시작하길 바랍니다, 
이것은 절대적으로 의무적인 문제입니다. 
모든 문제는 의무적이지만, 여러분도 알다시피 
여러분이 한 두 개를 건너 뛰면 
크게 문제가 되지 않습니다. 

English: 
And we also have,
you can write it in any
language you want,
including Matlab,
Python, whatever your favorite,
the solutions will be written
in Java and Python.
OK, so the fastest solutions
are likely to be written in c.
OK, you can also do it in
assembly language if you care
to.
You laugh.
I used to be in assembly
language programmer back in the
days of yore.
OK, so I do encourage people to
get started on this because let
me mention, the other thing is
that this particular problem on
this problem set is an
absolutely mandatory problem.
OK, all the problems are
mandatory, but as you know you
can skip them and it doesn't
hurt you too much if you only
skip one or two.
This one, you skip,

English: 
hurts big time:
one letter grade.
It must be done.

Korean: 
이번 것은 크게 문제가 될 겁니다. 
반드시 하세요.
