标签: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