感觉就是最长公共子序列的一个变形(虽然我也没做过LCS啦= =)。
转移方程见代码吧。这里有一个要说的地方,如果a[i] == a[j]的时候,为什么不需要像不等于的时候那样减去一个dp[i-1][j-1]呢?其实是要减去的,然后我们注意+1是什么呢?这两个位置是相同的,那么这一对组合是1,然后包含这一个,在dp[i-1][j-1]中相同的又可以拿出来加一遍了,因此就抵消了~
代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 typedef long long ll; 6 const int mod = 1000000007; 7 const int N = 1000 + 5; 8 9 int a[N],b[N],dp[N][N]; 10 int n,m; 11 12 int main() 13 { 14 while(scanf("%d%d",&n,&m)==2) 15 { 16 for(int i=1;i<=n;i++) scanf("%d",a+i); 17 for(int i=1;i<=m;i++) scanf("%d",b+i); 18 for(int i=1;i<=n;i++) 19 { 20 for(int j=1;j<=m;j++) 21 { 22 if(a[i]==b[j]) dp[i][j] = (dp[i][j-1] + dp[i-1][j] + 1) % mod; 23 else dp[i][j] = (dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1]) % mod; 24 if(dp[i][j] < 0) dp[i][j] += mod; 25 } 26 } 27 printf("%d\n",dp[n][m]); 28 } 29 }
时间: 2024-10-10 09:27:29