题意:求解两个序列的相同子序列个数(位置不同为不同)。
题解:dp[i][j] 表示A[i]==B[j],以A[i]这个位置的字符为结尾的序列个数。则,dp[i][j] = sum(dp[a][b]) a<i&&b<j。用个数组维护一下和就可以O(1)转移了。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 1010
typedef long long LL;
LL s[N][N];
LL dp[N][N];
int A[N],B[N];
#define MOD 1000000007
int main(){
int n,m;
while(cin>>n>>m){
for(int i=1;i<=n;i++){
cin>>A[i];
}
for(int i=1;i<=m;i++){
cin>>B[i];
}
memset(s,0,sizeof(s));
memset(dp,0,sizeof(dp));
LL ret = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(A[i]==B[j]){
dp[i][j]=s[i-1][j-1]+1;
ret = (ret+dp[i][j])%MOD;
}
s[i][j] = (s[i-1][j]+s[i][j-1]+dp[i][j]-s[i-1][j-1])%MOD;
}
}
cout<<(ret+MOD)%MOD<<endl;
}
return 0;
}