hdu5791(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5791

参考博客:https://blog.csdn.net/wuxuanyi27/article/details/52116674

Two

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2815    Accepted Submission(s): 1206


Problem Description
Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not same. A' is a subsequence of A. B' is a subsequence of B. The subsequnce can be not continuous. For example, {1,1,2} has 7 subsequences {1},{1},{2},{1,1},{1,2},{1,2},{1,1,2}. The answer can be very large. Output the answer mod 1000000007.
 
Input
The input contains multiple test cases.

For each test case, the first line cantains two integers N,M(1N,M1000). The next line contains N integers. The next line followed M integers. All integers are between 1 and 1000.
 
Output
For each test case, output the answer mod 1000000007.
 
Sample Input
3 2 1 2 3 2 1 3 2 1 2 3 1 2
 
Sample Output
2 3
题目大意:给你两个集合,长度分别为n和m,需要你求出他们相同的子序列个数。
解题思路:看起来有点像最长公共子序列,不过有点不一样。我们可以很容易确定状态,用dp[i][j]表示第一个序列的前i个元素和第二个序列的前j个元素相同子序列的个数。关键是推导出状态方程,如果第一序列第i个元素和第二个序列的第j个元素不相同的话,我们需要考虑两种情况,如果第一个序列没有第i个元素,他们相同的子序列个数加上如果第二个序列没有第j个元素,他们相同子序列的个数,同时再减去dp[i-1][j-1],,因为在之前将第一个序列前i-1和第二个序列前j-1计算了两边,就可以的得到:dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]。当第一个序列的第i个元素等于第二个序列的第j个元素的话,需要加上i与j相同的一个之外,还需要加上dp[i-1][j-1],因为dp[i-1][j-1]可以与i配对相同,也可以与j配对相同,于是就需要重复计算一次。
dp[i][j]=dp[i-1][j]+dp[i][j-1]+1。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 const int MOD=1e9+7;
 7 const int maxn=1005;
 8 ll dp[maxn][maxn];
 9 int n,m;
10 int a[maxn],b[maxn];
11 
12 int main()
13 {
14     while(cin>>n>>m)
15     {
16         memset(dp,0,sizeof(dp));
17         for (int i=1;i<=n;i++)
18         cin>>a[i];
19         for (int i=1;i<=m;i++)
20         cin>>b[i];
21         for(int i=1;i<=n;i++)
22         {
23             for(int j=1;j<=m;j++)
24             {
25                 if(a[i]==b[j]) dp[i][j]=(dp[i-1][j]+dp[i][j-1]+1)%MOD;
26                 else dp[i][j]=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1])%MOD;
27             }
28         }
29         cout<<(dp[n][m]+MOD)%MOD<<endl;
30     }
31 }
原文地址:https://www.cnblogs.com/zjl192628928/p/9355562.html