题解
题目大意 给你两个数列让你求公共子序列数量
使用动态规划求解 d[i][j]表示a数列的前i个长度和b数列的前j个长度的公共子序列的数量 遍历a和b的每个位置
如果当前位置不相等则等于 a长度-1的+b长度-1的答案再减去重复的部分a和b长度-1的答案
d[i][j] = d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1]
如果当前位置相等则等于 不相等的答案+a和b长度都减一的答案(在前面追加当前字符)+单独的当前字符的一个答案
d[i][j] = d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1] + d[i - 1][j - 1] + 1
d[i - 1][j - 1]可以约掉
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int MAXN = 1e3 + 10;
ll d[MAXN][MAXN]; //a前i位 b前j位
int a[MAXN], b[MAXN];
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int N, M;
while (cin >> N >> M)
{
memset(d, 0, sizeof(d));
for (int i = 1; i <= N; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= M; i++)
scanf("%d", &b[i]);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
{
if (a[i] == b[j]) //相同则等于不相同的加上a和b都减1后面追加当前 和当前相同的1贡献 化简得式子
d[i][j] = d[i - 1][j] + d[i][j - 1] + 1 % MOD;
else //如果当前位不同则等于a长度减1加b长度减1并减去长度都减1的重复部分
d[i][j] = (d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1] + MOD) % MOD;
}
cout << d[N][M] << endl;
}
return 0;
}