zoukankan      html  css  js  c++  java
  • LightOJ 1013 Love Calculator 【DP(LCS变形)】

    题目链接

    题意

    给两个字符串,求长度最短的字符串的长度以及个数,使得给出的两个串都是这个串的子串。

    分析

    LCS的变形,首先长度自然是len(s1)+len(s2)-len(LCS)。关键是有多少个这样的字符串。现在知道有两种DP的方法。

    题意

    给两个字符串,求长度最短的字符串的长度以及个数,使得给出的两个串都是这个串的子串。

    分析

    LCS的变形,首先长度自然是len(s1)+len(s2)-len(LCS)。关键是有多少个这样的字符串。现在知道有两种DP的方法。

    方法一(三维DP)

    设状态:
    dp[i][j][k]s1js2ki

    那么转移方程:
    考虑当前这个状态是由上一个状态加一个字母而来,那么转移时考虑这个字母是不是LCS中的字母

    dp[i][j][k]={dp[i1][j1][k1](s1[i]=s2[j])dp[i1][j][k1]+dp[i1][j1][k](s1[i]s2[j])

    注意初始化要把所有dp[i][i][0]和dp[i][0][i]初始化为0

    (也可以递推来写,不过初始化不一样,见下面代码)

    方法二(二维DP)

    看到这种方法在求LCS的时候就把个数求了出来,暂时没弄懂,思考过后再来补充一波
    设状态:
    dp[i][j]s1is2jLCS
    cnt[i][j]s1is2j
    转移方程:
    LCS按常规方法求

    cnt[i][j]=cnt[i1][j1](s1[i]=s2[j]))cnt[i1][j](s1[i]s2[j] and dp[i1][j]>dp[i][j1])cnt[i][j1](s1[i]s2[j] and dp[i1][j]<dp[i][j1])cnt[i][j1]+cnt[i1][j](s1[i]s2[j] and dp[i1][j]=dp[i][j1])

    AC代码

    姿势1

    //LightOJ 1013 Love Calculator
    //AC 2016-8-9 16:12:26
    //DP
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define input(x) scanf("%d",&(x))
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int T;
    char s1[100],s2[100];
    long long dp[100][100][100];
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        input(T);
        for(int kase=1;kase<=T;++kase)
        {
            scanf("%s %s",s1+1,s2+1);
            int len1=strlen(s1+1),len2=strlen(s2+1);
            cls(dp);
            for(int i=0;i<=max(len1,len2);++i)
                dp[i][i][0]=dp[i][0][i]=1;
            for(int i=1;i<=len1+len2;++i)
            {
                for(int j=1;j<=len1;++j)
                {
                    for(int k=1;k<=len2;++k)
                    {
                        if(s1[j]==s2[k]) dp[i][j][k]=dp[i-1][j-1][k-1];
                        else dp[i][j][k]=dp[i-1][j][k-1]+dp[i-1][j-1][k];
                    }
                }
            }
            int res=max(len1,len2);
            for(;res<=len1+len2;++res)
                if(dp[res][len1][len2]) break;
            printf("Case %d: %d %lld
    ",kase,res,dp[res][len1][len2]);
        }
        return 0;
    }

    姿势2

    //LightOJ 1013 Love Calculator
    //AC 2016-8-9 16:25:35
    //DP
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define input(x) scanf("%d",&(x))
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int T;
    char s1[50],s2[50];
    int dp[50][50];
    long long cnt[100][50][50];
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        input(T);
        for(int kase=1;kase<=T;++kase)
        {
            scanf("%s",s1+1);scanf("%s",s2+1);
            int len1=strlen(s1+1),len2=strlen(s2+1);
            cls(dp);
            for(int i=1;i<=len1;++i)
            {
                for(int j=1;j<=len2;++j)
                {
                    if(s1[i]==s2[j])
                        dp[i][j]=dp[i-1][j-1]+1;
                    else
                        dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
            cls(cnt);
            int len=len1+len2-dp[len1][len2];
            cnt[0][0][0]=1;
            for(int i=0;i<=len;++i)
            {
                for(int j=0;j<=len1;++j)
                {
                    for(int k=0;k<=len2;++k)
                    {
                        if(s1[j+1]==s2[k+1])
                            cnt[i+1][j+1][k+1]+=cnt[i][j][k];
                        else
                        {
                            cnt[i+1][j+1][k]+=cnt[i][j][k];
                            cnt[i+1][j][k+1]+=cnt[i][j][k];
                        }
                    }
                }
            }
            printf("Case %d: %d %lld
    ",kase,len,cnt[len][len1][len2]);
        }
        return 0;
    }

    姿势3

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define input(x) scanf("%d",&(x))
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int T;
    char s1[40],s2[40];
    int dp[40][40];
    long long cnt[40][40];
    
    long long fact[40];
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        input(T);
        for(int kase=1;kase<=T;++kase)
        {
            scanf("%s %s",s1+1,s2+1);
            cls(dp);cls(cnt);
            int len1=strlen(s1+1),len2=strlen(s2+1);
            for(int i=0;i<=len1;++i)
                cnt[i][0]=1;
            for(int i=0;i<=len2;++i)
                cnt[0][i]=1;
            for(int i=1;i<=len1;++i)
            {
                for(int j=1;j<=len2;++j)
                {
                    if(s1[i]==s2[j])
                    {
                        dp[i][j]=dp[i-1][j-1]+1;
                        cnt[i][j]+=cnt[i-1][j-1];
                    }
                    else
                    {
                        if(dp[i-1][j]>dp[i][j-1])
                        {
                            dp[i][j]=dp[i-1][j];
                            cnt[i][j]=cnt[i-1][j];
                        }
                        else if(dp[i-1][j]<dp[i][j-1])
                        {
                            dp[i][j]=dp[i][j-1];
                            cnt[i][j]=cnt[i][j-1];
                        }
                        else
                        {
                            dp[i][j]=dp[i][j-1];
                            cnt[i][j]=cnt[i][j-1]+cnt[i-1][j];
                        }
                    }
                }
            }
            for(int i=0;i<=len1;++i)
            {
                for(int j=0;j<=len2;++j)
                    cout<<cnt[i][j]<<" ";
                cout<<endl;
            }
            printf("Case %d: %d ",kase,len1+len2-dp[len1][len2]);
            cout<<cnt[len1][len2]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    使用Strust2框架写HelloWorld
    MyEclipse10搭建Strust2开发环境
    MyEclipse使用总结——在MyEclipse中设置jsp页面为默认utf-8编码
    HTML一些标签注意事项
    Spring常用注解
    VB.NET中Module的概念
    vs2008发布项目失败的解决方法
    Java开发中的一些小技巧
    DNS服务器
    关于在Struts2的Action中使用domain模型接收参数的问题
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580592.html
Copyright © 2011-2022 走看看