• 动态规划(7)——最长公共子序列(NOYJ37回文字符串)


    题目大意:

        给一个字符串,求它最少需要添加几个字符变为回文串。

    思路:

            求出该字符串的逆序串,求两者之间的最长公共子序列的长度len,再用该字符串的长度strLen-len即得到最少需要添加的字符的个数,本题得解。

        最长公共子序列的思路:

        int a[]={1,2,4,5,7}; len_a=5; i=len_a;i--;i指向7然后是5,4,2,1;

        int b[]={1,4,5};len_b=3;j=len_b;j--;j指向5然后是4最后是1;

        如果a[i]==b[j];dp[i][j]=dp[i-1][j-1]+1;

        如果a[i]!=b[j],dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

    AC代码如下:

        

     
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<cstring>
    int dp[1005][1005];
    using namespace std;
    
    int main()
    {
        int n;
        scanf("%d",&n);//n组数据
        while(n--)
        {
            memset(dp,0,sizeof(dp));
            string a;
            cin>>a;//输入字符串
            int len=a.length();
            string b="";//将a的反串存到b中,可使用别的函数
            for(int i=len-1;i>=0;i--)
            {
                b+=a[i]; 
            }
            for(int i=1;i<=len;i++)//求a和b的最长公共子序列的长度
            {
                for(int j=1;j<=len;j++)
                {
                    if(a[i-1]==b[j-1])
                        dp[i][j]=dp[i-1][j-1]+1;
                    else
                        dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];        
                }        
            }
            int max=0;
            for(int i=0;i<=len;i++)
            {
                for(int j=0;j<=len;j++)
                {
                    if(max<dp[i][j])
                    {
                        max=dp[i][j];  
                    }        
                }        
            }
            printf("%d
    ",len-max);//输出结果
        } 
        return 0;
    } 
            
    

      求一个字符串的反串儿可以直接用reverse(a.begin(),a.end())函数或者assign(a.begin(),a.end())而不是用for循环:

         1、将a自身翻转, std:: void reverse(a.begin(), a.end());
         2、将a反转到b里面, s1.assign(a.rbegin(), a.rend());

    例子:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int main()
    {
        string a;string b;
        a="abcdefg";
        cout<<"原始"<<a<<" "<<b<<endl;
        b.assign(a.rbegin(),a.rend());//b将变为“gfedcba”,a不变
        cout<<"改变b:"<<a<<" "<<b<<endl;
        reverse(a.begin(),a.end());//a将变为“gfedcba”
        cout<<"改变a:"<<a<<" "<<b<<endl;
        return 0;
    }
    

    结果:

      

  • 相关阅读:
    使用Navicat for Oracle工具连接oracle
    ArcGIS中的坐标系统定义与投影转换(转)
    随鼠标移动在状态栏实时显示地图坐标(转载)
    SQL Server 2014 中废止的数据库引擎功能
    sql server 对已有数据的表,添加核查约束 [失败],请使用with nocheck 子句
    一次性预览多张图片时遇到的问题
    vue中注册多个全局过滤器
    关于vue-cli本地项目启动,手机端无法访问题(有可能是360安全卫士作的妖)
    关于vuex中mapActions传参小tips
    javaScript知识梳理String篇
  • 原文地址:https://www.cnblogs.com/xueniwawa/p/3741275.html
Copyright © 2020-2023  润新知