1. 程式人生 > >【codevs 1862】LCS問題+LCS的計數

【codevs 1862】LCS問題+LCS的計數

LCS的模版

#include<bits/stdc++.h>
using namespace std;
int len1,len2;
char a[5010],b[5010];
int dp[5010][5010];
int tot = 0;

int main()
{
	ios::sync_with_stdio(false);
	cin>>a+1>>b+1;
	len1 = strlen(a+1);
	len2 = strlen(b+1);
	len1--,len2--;
	for(int i=1;i<=len1;i++)	
	{
		for(int j=1;j<=len2;j++)
		{
			if(a[i]==b[j])
			{
				dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
			}
			else
			{
				dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
			}
		}
	}
	cout<<dp[len1][len2]<<endl<<tot;
	return 0;
}

然後這題還要統計LCS的個數。

參照一般的最長公共子序列的做法

if s1[i]==s2[j] then f[i][j]=f[i-1][j-1]+1

else f[i][j]=max(f[i][j-1],f[i-1][j])

然後我們用g[i][j]來表示方案數。

對於s1[i]==s2[i]

g[i][j]=g[i-1][j-1]+k1*g[i-1][j]+k2*g[i][j-1]

f[i][j]=f[i-1][j] then k1=1 else k1=0;

f[i][j]=f[i][j-1] then k2=1 else k2=0;

對於s1[i]!=s2[i]

g[i][j]=g[i-1][j-1]+k1*g[i-1][j]+k2*g[i][j-1]-k3*g[i-1][j-1]

f[i][j]=f[i-1][j] then k1=1 else k1=0;

f[i][j]=f[i][j-1] then k2=1 else k2=0;

f[i][j]=f[i-1][j-1] then k3=1 else k3=0;


#include <stdio.h>
#include <string.h>
#include<iostream>
#define max(a,b) a>b?a:b
using namespace std;
const int MOD=100000000;
int f[2][5001],g[2][5001];
char s1[5001],s2[5002];
int len1,len2;
int main() {
    scanf("%s%s",s1,s2);
    len1=strlen(s1);
    len2=strlen(s2);
    for (int i=len1-1;i>=1;--i) s1[i]=s1[i-1];
    for (int i=len2-1;i>=1;--i) s2[i]=s2[i-1];
    len1--;len2--;
    int pre=0,now=1;
    for (int i=1;i<=len2;i++)  
        g[0][i]=1;
    g[pre][0]=1;
    for (int i=1;i<=len1;++i) {
        for (int j=1;j<=len2;++j) f[now][j]=g[now][j]=0;
        g[now][0]=1;
        for (int j=1;j<=len2;++j)
            if(s1[i]==s2[j]) {
                f[now][j]=f[pre][j-1]+1;
                g[now][j]=g[pre][j-1],g[now][j]%=MOD;
                if (f[now][j]==f[pre][j]) g[now][j]+=g[pre][j],g[now][j]%=MOD;
                if (f[now][j]==f[now][j-1]) g[now][j]+=g[now][j-1],g[now][j]%=MOD;
            }
            else {
                f[now][j]=max(f[pre][j],f[now][j-1]);
                if (f[now][j]==f[pre][j]) g[now][j]+=g[pre][j],g[now][j]%=MOD;
                if (f[now][j]==f[now][j-1]) g[now][j]+=g[now][j-1],g[now][j]%=MOD;
                if (f[now][j]==f[pre][j-1]) g[now][j]-=g[pre][j-1],g[now][j]=(g[now][j]+MOD)%MOD;
            }//cout<<i<<" "<<j<<" "<<f[now][j]<<" "<<g[now][j]<<endl;}
        int t=pre;pre=now;now=t;
    }
    printf("%d\n%d\n",f[pre][len2],g[pre][len2]);
    return 0;
}