题目:P1279 字串距离
( ext{蒟蒻在DP之路上求索着})
这道题让我想起了在一个数字串中添加若干乘号使得乘积最大的问题。我开始考虑在前(i)个字符中插入(j)个字符的最小距离。后来我发现我不会转移(泪)。于是我打算一步一步,从分析开始找到其中的秘密。
思路
观察这道题是要求字符匹配然后求出最小的差值。因此相比于在字符串中插入空格,不如说是指定哪个字符与哪个字符配对,使得距离最小。于是我又联想到了P1140 相似基因,如果我们设(f[i][j])表示A串中的前i个字符和B串中的前j个字符进行决策所能带来的最小距离,会不会能够更简单呢?
然后根据通常DP的思路,我们应该考虑它的子问题.也就是假设我们前面已经求出了最小距离,接下来应该怎么办呢?在这个题目中我们有三种决策:
- 让(A_i)与(B_j)配对
- 让(A_i)与空格配对,把(B_i)留在后面
- 让(B_i)与空格配对,把(A_i)留在后面
我们找到了这三种决策,然后我们考虑能否转移,怎样转移.
如果我们让(A_i)与(B_j)配对,那么就是从(f[i-1][j-1])转移过来,然后加上这两位差的绝对值.
如果我们让(A_i)与空格配对,那么就是要求(B_j)已经和A中之前的字符或空格配对了,这样才能保证前i位对应前j位,然后加上常数K
同理,如果让(B_i)与空格配对,就要求(A_i)与B中之前的东西配对,然后加上常数K.
这样看来,我们转移到(f[i][j])时,需要从以下三个决策中取得最小值:
[1.f[i-1][j-1]+|A[i]-B[j]|( ext{两串配对})\
2.f[i-1][j]+K( ext{A与空格配对})\
3.f[i][j-1]+K( ext{B与空格配对})
]
然后还有一点就是我们显然是需要初始化的,不能什么都不匹配.所以我们让两串分别先配对空格.最后我们的目标是(f[lenth(A)][length(B)])
类似的问题还有很多,以后再继续讲解