LightOJ 1013 - Love Calculator LCS

题意:找一个串使给出的两个串都是它的子串,要求最短,求出最短长度,以及种类数。

思路:可以想到,当两个子串a,b拥有最长的公共子串为LCS时,那么可以求出的最短的串为lena+lenb-LCS。 那么接下来直接计算转移数就可以了,和平常求LCS的方法一样。DP[i][j][k]代表到选取了i个时已有j个a串的,k个b串的种类数。

 

 

 

/** @Date    : 2016-12-09-18.39
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version :
  */
#include<bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;

char a[110],b[110];
LL dp[110][50][50];
int main()
{
    int T;
    int cnt = 0;
    cin >> T;
    while(T--)
    {
        scanf("%s%s", &a, &b);
        int x = strlen(a);
        int y = strlen(b);
        int ma = 0;
        MMF(dp);
        for(int i = 1; i <= x; i++ )
        {
            for(int j = 1; j <= y; j++)
            {
                if(a[i-1] == b[j-1])
                    dp[0][i][j] = dp[0][i - 1][j - 1] + 1;
                else dp[0][i][j] = max(dp[0][i][j - 1], dp[0][i - 1][j]);
            }
        }
        int z = x + y - dp[0][x][y];
        MMF(dp[0]);
        dp[0][0][0] = 1;
        for(int i = 1; i <= z; i++)
        {
            for(int j = 0; j <= x; j++)
            {
                for(int k = 0; k <= y; k++)
                {

                    if(j > 0 && k > 0 && a[j-1] == b[k-1])
                    {
                        dp[i][j][k] += dp[i - 1][j - 1][k - 1];
                    }
                    else
                    {
                        if(j > 0)
                            dp[i][j][k] += dp[i - 1][j - 1][k];
                        if(k > 0)
                            dp[i][j][k] += dp[i - 1][j][k - 1];
                    }
                    //cout << dp[i][j][k] << endl;
                }
            }
        }
        printf("Case %d: %d %lld\n", ++cnt, z, dp[z][x][y]);

    }
    return 0;
}

posted @ 2016-12-09 22:31  Lweleth  阅读(190)  评论(0编辑  收藏  举报