这题是一个普通的dp,lcs变形,这里需要注意的是初始化,和这里需要使用高精度
阶段:以主串的字符顺序作为阶段,从后面枚举
状态:dp[i][j] 表示主串的第i个字符和子串的第j个字符匹配的方案数
dp[i][j+1] (stra[i] != strb[j])
状态转移:dp[i][j] ->
dp[i][j+1]+dp[i+1][j+1] (stra[i] == strb[j])
ans = dp[0][0];
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXLEN_A 105
#define MAXLEN_B 10005
#define MAXSIZE 128
char dp[MAXLEN_A][MAXLEN_B][MAXSIZE], stra[MAXLEN_A], strb[MAXLEN_B];
void add(int a_r, int a_c, int b_r, int b_c, int rst_r, int rst_c)
{
int bit(0), tmp;
for(int i = MAXSIZE-1; i >= 0; i --) {
tmp = bit+dp[a_r][a_c][i]-'0'+dp[b_r][b_c][i]-'0';
dp[rst_r][rst_c][i] = tmp%10+'0'; bit = tmp/10;
}
}
int dynamic_programming(void)
{
int lena(strlen(stra)), lenb(strlen(strb));
for(int i = 0; i <= lena; i ++) {
for(int j = 0; j <= lenb; j ++) {
for(int k = 0; k < MAXSIZE; k ++) {
dp[i][j][k] = '0';
}
}
}
for(int i = 0; i < MAXSIZE; i ++) {
dp[MAXLEN_A-1][MAXLEN_B-1][i] = '0';
}
for(int i = 0; i < lenb; i ++) {
dp[lena][i][MAXSIZE-1] = '1';
}
dp[lena][lenb][MAXSIZE-1] = (stra[lena-1] == strb[lenb-1])? '1' : '0';
for(int j = lenb-1; j >= 0; j -- ) {
for(int i = lena-1; i >= 0; i --) {
if( stra[i] == strb[j] ) {
add(i, j+1, i+1, j+1, i, j); continue;
}
add(i, j+1, MAXLEN_A-1, MAXLEN_B-1, i, j);
}
}
}
void output(const int &r, const int &c)
{
int idx(0);
for( ; idx < MAXSIZE && '0' == dp[r][c][idx]; idx ++) {}
if( idx == MAXSIZE ) {
printf("0\n"); return;
}
for( ; idx < MAXSIZE; idx ++) {
printf("%c", dp[r][c][idx]);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int cas;
scanf("%d", &cas);
for(; cas; cas --) {
scanf("%s %s", strb, stra);
dynamic_programming(); output(0, 0);
}
return 0;
}