类似于求最长公共子序列 要稍微变形
表示前缀子串A[1~i]和B[1~j]的公共子序列的个数
显然应该由转移过来
我们把分为两部分,一部分为公共部分,另一部分为非公共部分
显然公共部分是
我们只要减去公共部分就行
我们考虑一下
对于公共部分 我们可以在后面加上一个A[ i ]让它合理 非公共部分我们显然要计入答案 然后还会多出一个就是A[ i ]这个单独的数
这样说可能不清楚 我们举个例子
假如A序列是 1 2 4 1
B序列是4 1 3 考虑dp[2][4]
dp[2][3]的公共序列是:1,4
dp[1][4]的公共序列是:4
两者的公共部分是 4
非公共部分1显然要计入答案,公共部分4在 A[4]=B[2]时 可以在4后面加上A[4](把41计入答案)所以公共部分也可以计入答案 那么dp[i-1][j]+dp[i][j-1]都可以计入答案 最后+1(A[4]=B[2])
最后dp[2][4]=4,包括(1,4,41,1)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
int a[1003],b[1003];
ll dp[1003][1003];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
}
for(int j = 1; j <= m; j++){
scanf("%d",&b[j]);
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(a[i]==b[j]){
dp[i][j]=(dp[i-1][j]+dp[i][j-1]+1)%mod;
}else{
dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mod)%mod;
}
}
}
printf("%lld\n",dp[n][m]);
}
return 0;
}