HDU 5791 Two ——(LCS变形)

  感觉就是最长公共子序列的一个变形(虽然我也没做过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
",dp[n][m]);
28     }
29 }
原文地址:https://www.cnblogs.com/zzyDS/p/5800463.html