标签:pre soft 序列 优化 输出 组成 cdb sample style
题目描述
输入
输出
样例输入
ABCBDAB.
BACBBD.
样例输出
4
7
题解
dp
直接上求LCS的前缀最大值优化dp即可,同时维护一下出现次数(前缀和)。注意一下去重。
需要滚动数组。
具体看代码吧。
#include <cstdio>
#include <cstring>
#define N 5010
#define mod 100000000
int f[2][N] , g[2][N];
char A[N] , B[N];
int main()
{
int n , m , i , j , d;
scanf("%s%s" , A + 1 , B + 1);
n = strlen(A + 1) - 1 , m = strlen(B + 1) - 1;
for(i = 0 ; i <= m ; i ++ ) f[0][i] = 0 , g[0][i] = 1;
for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
{
f[d][0] = 0 , g[d][0] = 1;
for(j = 1 ; j <= m ; j ++ )
{
if(f[d ^ 1][j] > f[d][j - 1]) f[d][j] = f[d ^ 1][j] , g[d][j] = g[d ^ 1][j];
else if(f[d ^ 1][j] < f[d][j - 1]) f[d][j] = f[d][j - 1] , g[d][j] = g[d][j - 1];
else
{
f[d][j] = f[d ^ 1][j] , g[d][j] = (g[d ^ 1][j] + g[d][j - 1]) % mod;
if(f[d][j] == f[d ^ 1][j - 1]) g[d][j] = (g[d][j] - g[d ^ 1][j - 1] + mod) % mod;
}
if(A[i] == B[j])
{
if(f[d ^ 1][j - 1] + 1 > f[d][j]) f[d][j] = f[d ^ 1][j - 1] + 1 , g[d][j] = g[d ^ 1][j - 1];
else if(f[d ^ 1][j - 1] + 1 == f[d][j]) g[d][j] = (g[d][j] + g[d ^ 1][j - 1]) % mod;
}
}
}
printf("%d\n%d\n" , f[n & 1][m] , g[n & 1][m]);
return 0;
}
【bzoj2423】[HAOI2010]最长公共子序列 dp
标签:pre soft 序列 优化 输出 组成 cdb sample style
原文地址:http://www.cnblogs.com/GXZlegend/p/7763627.html