zoukankan      html  css  js  c++  java
  • 动态规划--P2758 编辑距离

    *传送

    动态规划最主要确定状态和转移方程,所以我的思路如下: 

    1.定义状态:

    确定$dp(i,j)$代表字符串A的前$i$个字符(包括第$i$个)变为字符串B的前$j$个(包括第$j$个)需要多少步。而$dp[l_1][l_2]$就是我们所要找的答案。

     

    2.转移方程:

    *删:$dp(i-1,j)+1$ //字符串A的前$i-1$个字符变为字符串B的前j个需要多少步 【把字符串的第i个字符(最后一个)删除了】,删除需要一步因此加1

    *添:$dp(i,j-1)+1$ //将$B[j]$字符加在A字符串的最后面即添加,同样可以理解为将$B[j]$字符删掉(因为不用再考虑了)。

    //字符串A的前$i$个字符变为字符串B的前$j-1$个需要多少步 添加需要一步因此加1

    *替:$dp(i-1,j-1)+1$ //字符串A和B的最后两个都相等了,因此都不用再考虑

    //字符串A的前$i-1$个字符变为字符串B的前$j-1$个需要多少步 添加需要一步因此加1

    *不变:$dp(i-1,j-1)$//字符串A和B的最后两个都相等,不考虑。

     

    反观这道题,如果两个字符串当前位置上相同,就可以不变,如果不相同就需要进行三种操作,取一种最小的。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cmath>
     5 #include <cstring> 
     6 using namespace std;
     7 char s1[2005],s2[2005];
     8 long long dp[2005][2005];
     9 int main(){
    10     scanf ("%s%s",s1+1,s2+1);
    11     int l1=strlen(s1+1),l2=strlen(s2+1);
    12     for (int i = 0;i <= l1;i++) dp[i][0]=i;
    13     for (int i = 0;i <= l2;i++) dp[0][i]=i;
    14     for (int i = 1;i <= l1;i++){
    15         for(int j = 1;j <= l2;j++){
    16             if (s1[i]==s2[j]) dp[i][j]=dp[i-1][j-1];
    17             else dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
    18         }
    19     }
    20     cout<<dp[l1][l2];
    21     return 0;
    22 }
  • 相关阅读:
    vim的script、function及command
    Vim中如何移动光标
    command模式下命令的匹配及help内容的搜索
    为什么vim编辑模式下ctrl-w可以前向删除单词及按键映射的展开
    gcc如何实现C++中函数auto返回类型推导
    sqlserver 列转行
    【java笔记】可变长参数(...)
    【c#笔记】可变长参数(params)
    【c#笔记】c#与java的差异:接口定义实现
    【java笔记】Calendar类的陷阱
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12400724.html
Copyright © 2011-2022 走看看