• 入坑动态规划!POJ 1458字符串最大公共子序列


    题干大概: 寻找两字符串最大公共子序列

    我是看了北大在coursera的网课,过来做这道题的,一开始我用递归试了一下;

    1 int maxlen(int len1,int len2){
    2      if(len1==0 || len2==0) return 0;
    3      if(s1[len1-1]==s2[len2-1]) return maxlen(len1-1,len2-1)+1;
    4      else return max(maxlen(len1-1,len2),maxlen(len1,len2-1));
    5 }

    妥妥的,没过,然后我就想如何把递归改成递推。

    想了想,没想出来,但我想到一个其他歪办法:

    从0位置比较两字符串,字符相同的话ans++,i1++,i2++,不相同的话初始turn_s1=true,turn_s1为真时,i1++,为假时i2++,turn_s1=false.

    怎么样,很妙吧

    妙个鬼...比如说,这个就过不了

    s1="21.",s2=".21",结果显示就是1...

    在我的印象里,动归似乎是一种非常奇妙的魔法(算法),可以用很简单的步骤解决问题;

    但是其实,动归也不过是一种遍历的策略;

    再牛逼的算法,对于这道题也不能够做到不完全遍历两个字符串就给出答案,你说是不是大兄弟。

    这是答案,是很妙的答案,也是最原始最暴利的答案:

    #include<iostream>
    #include<string.h>
    using namespace std;
    
    const int maxn=1000+20;
    int maxlen[maxn][maxn];
    
    int main(){
    	int i1,i2; 
    	char s1[maxn],s2[maxn];
    	while(scanf("%s%s",s1,s2)==2){
    i1=i2=0; int l1=strlen(s1); int l2=strlen(s2); for(int i=0;i<=l1;i++) maxlen[0][i]=0; //赋值 for(int i=0;i<=l2;i++) maxlen[i][0]=0; //赋值
    for(int i=1;i<=l1;i++){ //递推,和上文中的递归逻辑差不多 for(int l=1;l<=l2;l++){ if(s1[i-1]==s2[l-1]){maxlen[i][l]=maxlen[i-1][l-1]+1;continue;} //如果有相等的,直列下一轮 maxlen[i][l]=max(maxlen[i-1][l],maxlen[i][l-1]); //说明没有相等,max一下 }
    } cout<<maxlen[l1][l2]<<endl; } return 0; }


    最后我用记忆递归试了一下,发现不但能过,还比上面的快,mmp..
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    const int maxn=1000+20;
    int maxlen[maxn][maxn];
    
    int main(){
        int i1,i2; 
        char s1[maxn],s2[maxn];
        while(scanf("%s%s",s1,s2)==2){
            i1=0;i2=0;
            int l1=strlen(s1);
            int l2=strlen(s2);
            for(int i=0;i<=l1;i++) maxlen[0][i]=0;
            for(int i=0;i<=l2;i++) maxlen[i][0]=0;
            for(int i=1;i<=l1;i++){
                for(int l=1;l<=l2;l++)
            {
                if(s1[i-1]==s2[l-1]) {
                maxlen[i][l]=maxlen[i-1][l-1]+1;continue;}
                maxlen[i][l]=max(maxlen[i-1][l],maxlen[i][l-1]);
            }}
            cout<<maxlen[l1][l2]<<endl;
        }
        return 0;
    }


    柳暗花明又一村
  • 相关阅读:
    jquery.ajax,vue-resource,axios拦截器实现与携带cookie
    vs code 常用插件及说明
    Js/Jquery获取网页屏幕可见区域高度(转)
    vue的爬坑之路(三)之-----基于vue-cli的VueAwesomeSwiper轮播滑块插件的使用及常见问题(转)
    js中的深拷贝与浅拷贝
    沉浸式状态栏 关于状态栏高度的获取
    Cordova 常用命令及插件(转)
    video control
    canvas添加水印
    疑惑
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8430603.html
Copyright © 2020-2023  润新知