• 【简单dp】poj 1458 最长公共子序列【O(n^2)】【模板】


    最长公共子序列可以用在下面的问题时:给你一个字符串,请问最少还需要添加多少个字符就可以让它编程一个回文串?

    解法:ans=strlen(原串)-LCS(原串,反串);

     

    Sample Input

    abcfbc         abfcab
    programming    contest 
    abcd           mnp

    Sample Output

    4
    2
    0


    代码:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    char s[10100], t[10100];
    int dp[10100][10100];
    //dp[i+1][j+1]:表示序列s的前i个和序列t的前j个的最长公共子序列
    //因为字符串从0下标开始存储的 dp[][]数组的0行 0列都被初始化为0
    //比如说s[0]=t[0] 就会推出dp[0+1][0+1]=dp[0][0]+1=1
    //dp[1][1]=1 也就是s的前1个和t的前1个序列中最长序列为1
    
    int LCS()
    {
        int i, j;
        int len1=strlen(s); int len2=strlen(t);
    
        for(i=0; i<len1; i++) dp[i][0]=0;
        for(i=0; i<len2; i++) dp[0][i]=0;
        
        
        for(i=0; i<len1; i++){
            for(j=0; j<len2; j++){
                if(s[i]==t[j]) dp[i+1][j+1]=dp[i][j]+1;
    
                else
                    dp[i+1][j+1]=max(dp[i+1][j], dp[i][j+1]);
            }
        }
        return dp[len1][len2];
    }
    
    int main()
    {
        while(scanf("%s", s)!=EOF){
            scanf("%s", t);
            int ans=LCS();
            printf("%d
    ", ans );
        }
        return 0;
    }
    

     现在我修改了字符串开始存储的位置,这样:scanf("%s", s+1); 从下标1开始存储,注意 正确的 len=strlen(s+1); 

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    char s[10100], t[10100];
    int dp[10100][10100];
    //dp[i+1][j+1]:表示序列s的前i个和序列t的前j个的最长公共子序列
    //因为字符串从0下标开始存储的 dp[][]数组的0行 0列都被初始化为0
    //比如说s[0]=t[0] 就会推出dp[0+1][0+1]=dp[0][0]+1=1
    //dp[1][1]=1 也就是s的前1个和t的前1个序列中最长序列为1
    
    int LCS()
    {
        int i, j;
        int len1=strlen(s+1); int len2=strlen(t+1);
    
        for(i=0; i<=len1; i++) dp[i][0]=0;
        for(i=0; i<=len2; i++) dp[0][i]=0;
    
    
        for(i=1; i<=len1; i++){
            for(j=1; j<=len2; j++){
                if(s[i]==t[j]) dp[i][j]=dp[i-1][j-1]+1;
    
                else
                    dp[i][j]=max(dp[i-1][j], dp[i][j-1]);
            }
        }
        return dp[len1][len2];
    }
    
    int main()
    {
        while(scanf("%s", s+1)!=EOF){
            scanf("%s", t+1);
            int ans=LCS();
            printf("%d
    ", ans );
        }
        return 0;
    }
    
  • 相关阅读:
    cmd中删除、添加、修改注册表命令
    修改注册表使win server 2012R2开机进入桌面而不是开始界面
    win8.1/2012R2上面安装flash debugger
    ANT中的copy和move标签
    用maven在MANIFEST.MF文件中的Class-Path中增加当前目录(.)
    通过ANT生成MANIFEST.MF中的Class-Path属性
    Junit4进行参数化测试
    DbUnit入门实战
    oracle查看当前正在使用的数据库
    左偏树 P3377【模板】左偏树(可并堆)
  • 原文地址:https://www.cnblogs.com/yspworld/p/4712573.html
Copyright © 2020-2023  润新知