• 简单LCS HDU_1503


    学了一下最长公共子串,它是属于dp里面的 dp=max{(i,j-1),(i-1,j),(i-1,j-1)+d}问题,不得不说,规划方向确实厉害,当然这只适用于两个字符串匹配的问题,n个字符串的话,我查了一下,要用后缀数组,这个以后再来弄吧。

    比较难的是记录公共字串,在DP的时候记录好搜索的方向,就可以询步骤得到公共串。尤其1503这题呢,除了把公共部分打印出来,还要把非公共部分打印出来。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    char a[105] , b[105];
    int dp[105][105];
    int rec[105][105];
    int dir[105][105];
    int LCS(int r,int c)
    {
        if (dp[r][c]>=0) return dp[r][c]; //用DP+记忆化搜索写的LCS
        if (a[r-1]==b[c-1]){
            dp[r][c]=LCS(r-1,c-1)+1;
            dir[r][c]=1;
        }
        else
        {
            int dp1=LCS(r-1,c);
            int dp2=LCS(r,c-1);
            if (dp1>dp2){
                dp[r][c]=dp1;
                dir[r][c]=2; //用dir记录规划的方向
            }
            else
            {
                dp[r][c]=dp2;
                dir[r][c]=3;
            }
        }
        return dp[r][c];
    }
    void output(int r,int c)//已经用dir记录了规划方向,这里用递归将字符串还原出来
    {
        if (r==0&&c==0) return; //一开始这里犯糊涂了,写成或,要知道只有一个为0的话,还要把其他非公共部分打印出来,还得继续下去。
       // cout<<"dir"<<" "<<r<<" "<<c<<" "<<dir[r][c]<<endl;
        if (dir[r][c]==1){
            output(r-1,c-1);
            printf("%c",a[r-1]);
        }
        if (dir[r][c]==2){ //此时a[r-1]相当于被抛弃了,所以可以打印了,下面同理
            output(r-1,c);
            printf("%c",a[r-1]);
        }
        if (dir[r][c]==3){
            output(r,c-1);
            printf("%c",b[c-1]);
        }
    }
    int main()
    {
        while (scanf("%s%s",a,b)!=EOF)
        {
            int len1=strlen(a);
            int len2=strlen(b);
            int i,j;
            for (i=0;i<=len1;i++){
                for (j=0;j<=len2;j++){
                    dp[i][j]=-1;
                    if (i==0||j==0) dp[i][j]=0;
                    if (i==0) dir[i][j]=3;//为了让output把所有非公共部分也打印完,得预先把这些设置好
                    if (j==0) dir[i][j]=2;
                }
            }
            int ans=LCS(len1,len2);
            output(len1,len2);
            //printf("%d",ans);
            putchar('
    ');
        }
    }
  • 相关阅读:
    CF493D Vasya and Basketball (二分)
    CF734C Anton and Making Potions (二分)
    CF785C Anton and Fairy Tale (二分)
    HDU3047 Zjnu Stadium (带权并查集)
    POJ1795 DNA Laboratory (状压dp)
    BZOJ.3524.[POI2014]Couriers(主席树)
    BZOJ.3932.[CQOI2015]任务查询系统(主席树 差分)
    洛谷.3835.[模板]可持久化平衡树(fhq treap)
    SDOI2013 R1 Day2
    洛谷.3919.[模板]可持久化数组(可持久化线段树/平衡树)
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3338954.html
Copyright © 2020-2023  润新知