poj 3356 AGTC(线性dp)
题目链接:http://poj.org/problem?id=3356
思路分析:题目为经典的编辑距离问题,其实质为动态规划问题;
编辑距离问题定义:给定一个字符串source,可以对其进行复制,替换,删除,增加操作,另外根据具体情况已经规定了每种操作的cost,现在要求求出一个操作序列,使其变为一个给定的字符串dest,并且该操作序列的cost的和最小(在该题目中复制开销为0,其他开销为1);
该问题为动态规划问题,先对该问题进行分析:
1)发掘最优子结构:
假设源字符串为S[0, 1, 2,..,n-1],其长度为n,目标字符串为D[0, 1, 2, ...., m-1],长度为m,则该问题转换为求一个cost最小的操作序列将
S[0,1,2,...,n-1]转换为D[0, 1, 2, ...., m-1];先考虑如何将S[0]转换为D[0];为了将S[0]转换为D[0],我们先选择一个操作,假设该操作是产生最
优的操作序列的第一个操作,这样我们就能将S[0]转换为D[0],则原来的问题在该操作后产生了一个子问题(在不同的动态规划问题中可能会产
生不同的子问题个数),即求一个cost最小的操作序列将S[1, 2, ... , n-1]转换为D[1, 2, ..., m-1],我们可以证明该子问题的最优解可以构造出原
来问题的最优解,这样我们就发现了该问题的最优子结构;另外,我们还需要考虑第一步的选择有多少种(不同动态规划问题的选择的可能性的
种类数目不同),即将S[0]转换为D[0]可以有多少种操作方法,明显在这个问题中有4种;
2)重叠子问题
如果该问题的递归算法反复地求解子问题,那么我们就称该最优化问题具有重叠子问题性质;在分治算法中,递归算法会生成全新的子问题,
子问题与子问题之间是无关的;而动态规划算法不同,如求斐波那契数列的递归算法中求数列f[n]需要求解f[n-1]与f[n-2],而f[n-1]=f[n-2]+f[n-3],
可以看到,在求斐波那契数列的递归算法中f[n-2]被求解多次,则求具有重叠子问题的结构,但是求斐波那契数列算法不是动态规划算法,因为其
不具有最优子结构,这里提出该问题是让大家对重叠子问题有一个具体的认识;现在,我们可以明显看到,在求解编辑距离问题中,我们做出一次
选择,就会产生一个子问题,因为在每一步中我们可能会做出多个选择,所以会求解多个相同的子问题,如在第一步中,我们可以选择复制(如果
S[0]==D[0]),删除,替换,增加操作,每个选择的操作就会产生相同的子问题,即求解S[1,2, .., m]转换D[1, 2, ..., n]的最小的cost的操作序列;
所以该问题具有重叠子问题;
3)解法:
对于该问题,我们刻画该问题的问题空间:假设dp[i][j]表示从字符串S[i, i+1, i+2, ...., m-1]转换为字符串D[j, j+1, j+2, ...., n-1]的操作序列的最小的cost和,
则原问题为求dp[0][0];
对于特殊的情况:
dp[i, n] = m-i,表示使S[i, i+1, ...,m-1]转换为空字符串,只能删除m-i个字符,所以最小的cost和为m-i;
dp[m, j] = n-j,表示使空字符串转换为D[j, j+1, ..., n-1],则只能增加n-j个字符,所以最小的cost和为n-j;
关于选择的可能:
<1>复制:dp[i, j] = dp[i+1, j+1], 如果S[i]==D[j],可以使用复制操作;
<2>删除:dp[i, j] = dp[i+1, j] + 1,删除操作cost为1,删除S[i],子问题为dp[i+1, j];
<3>替换:dp[i, j] = dp[i+1, j+1] + 1,替换操作只能在S[i]与D[j]不相等时才能选择;
<4>增加:dp[i, j] = dp[i, j+1] + 1,同样的,增加操作cost为1;
则该问题的动态规划方程已经给出,可以求解该问题;
代码如下:
#include <cstdio>
#include <iostream>
using namespace std; const int MAX_N = + ;
char source[MAX_N], dest[MAX_N];
int dp[MAX_N][MAX_N]; inline int Min(int a, int b) { return a > b ? b : a; } int main()
{
int s_len, d_len; while(scanf("%d %s", &s_len, source) != EOF)
{
scanf("%d %s", &d_len, dest); memset(dp, , sizeof(dp));
for (int i = ; i <= d_len; ++i)
dp[s_len][i] = d_len - i;
for (int i = ; i <= s_len; ++i)
dp[i][d_len] = s_len - i;
for (int i = s_len - ; i >= ; --i)
{
for (int j = d_len - ; j >= ; --j)
{
int min_cost = ; min_cost = Min(min_cost, dp[i + ][j] + );
min_cost = Min(min_cost, dp[i][j + ] + );
if (source[i] == dest[j])
min_cost = Min(min_cost, dp[i + ][j + ]);
else
min_cost = Min(min_cost, dp[i + ][j + ] + );
dp[i][j] = min_cost;
}
}
printf("%d\n", dp[][]);
} return ;
}
poj 3356 AGTC(线性dp)的更多相关文章
- POJ 3356 AGTC(最小编辑距离)
POJ 3356 AGTC(最小编辑距离) http://poj.org/problem?id=3356 题意: 给出两个字符串x 与 y,当中x的长度为n,y的长度为m,而且m>=n.然后y能 ...
- POJ 3356.AGTC
问题简述: 输入两个序列x和y,分别执行下列三个步骤,将序列x转化为y (1)插入:(2)删除:(3)替换: 要求输出最小操作数. 原题链接:http://poj.org/problem?id=335 ...
- POJ 2479-Maximum sum(线性dp)
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33918 Accepted: 10504 Des ...
- POJ 3356 AGTC(DP求字符串编辑距离)
给出两个长度小于1000的字符串,有三种操作,插入一个字符,删除一个字符,替换一个字符. 问A变成B所需的最少操作数(即编辑距离) 考虑DP,可以用反证法证明依次从头到尾对A,B进行匹配是不会影响答案 ...
- POJ 1745 Divisibility (线性dp)
Divisibility Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10598 Accepted: 3787 Des ...
- POJ 3356 AGTC(DP-最小编辑距离)
Description Let x and y be two strings over some finite alphabet A. We would like to transform x int ...
- POJ 3356 AGTC(最长公共子)
AGTC Description Let x and y be two strings over some finite alphabet A. We would like to transform ...
- POJ 3356(最短编辑距离问题)
POJ - 3356 AGTC Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Desc ...
- poj 1050 To the Max(线性dp)
题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
随机推荐
- oracle 插入含&字符串
1.创建表 SQL> create table t(id number,name varchar2(20)); 表已创建. 2.常规方式插入 SQL> insert into t valu ...
- SimpleXML 使用详细例子
要处理XML 文件,有两种传统的处理思路:SAX 和DOM.SAX 基于事件触发机制, 对XML 文件进行一次扫描,完成要进行的处理:DOM 则将整个XML 文件构造为一棵DOM 树,通过对DOM 树 ...
- css2实现尖角箭头式导航
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- 从零开始PHP学习 - 第五天
写这个系列文章主要是为了督促自己 每天定时 定量消化一些知识! 同时也为了让需要的人 学到点啥~! 本人技术实在不高!本文中可能会有错误!希望大家发现后能提醒一下我和大家! 偷偷说下 本教程最后的目 ...
- [LeetCode]题解(python):138-Copy List with Random Pointer
这道题目不是太懂,参考了http://www.cnblogs.com/zuoyuan/p/3745126.html的博客. 题意: A linked list is given such that e ...
- 黑马12期day01之html&css
html注释:<!-- --> html中不支持空格.回车.制表符都会被解析成一个空格 <pre></pre>标签内以上三个会被正常解析. <font> ...
- Springmvc+Spring+Hibernate搭建方法及实例
Springmvc+Spring+Hibernate搭建方法及实例
- java字符串函数及理解
Java中的字符串也是一连串的字符.但是与许多其他的计算机语言将字符串作为字符数组处理不同,Java将字符串作为String类型对象来处理.将字符串作为内置的对象处理允许Java提供十分丰富的功能特性 ...
- MZL's xor
MZL's xor Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other) Total Sub ...
- o怎么样racle输入dmp数据库文件
Oracle进出口数据imp/exp等价物oracle数据恢复和备份. exp命令可以从远程数据库传输数据server出到本地的dmp文件,imp命令能够把dmp文件从本地导入到远处的数据库serve ...