hdu 1423 Greatest Common Increasing Subsequence 最长公共上升子序列 LCIS

dp[i][j]表示,考虑a序列1...i,b序列1...j,以b[j]结尾的最长LCIS长度。

考虑转移方程

若a[i] != b[j],则dp[i][j]  = dp[i - 1][j]

若a[i] == b[j],则dp[i][j] = max(dp[i - 1][k]) + 1 (b[k] < b[j] && k < j)

这么做是n*m^2的

我们看a[i] == b[j]时,b[k] < b[j]可以等价于 b[k] < a[i],而我们最外层循环为i,对于j来说a[i]是不变的。也就是说,我们可以把这个最优转移循环时顺便处理出来,复杂度就变成n*m了。

 1 #include <cstdio>
 2 #include <stack>
 3 using namespace std;
 4 stack <int> stk;
 5 int T,n,m,res,rj,a[510],b[510],dp[510][510];
 6 int main()
 7 {
 8     for (scanf("%d",&T);T != 0;T--)
 9     {
10         scanf("%d",&n);
11         for (int i = 1;i <= n;i++)
12             scanf("%d",&a[i]);
13         scanf("%d",&m);
14         for (int i = 1;i <= m;i++)
15             scanf("%d",&b[i]);
16         for (int i = 1;i <= n;i++)
17         {
18             int maxn = 0;
19             for (int j = 1;j <= m;j++)
20             {
21                 if (a[i] != b[j])
22                 {
23                     dp[i][j] = dp[i - 1][j];
24                 }else
25                 {
26                     dp[i][j] = maxn + 1;
27                 }
28                 if (b[j] < a[i] && dp[i - 1][j] > maxn)
29                 {
30                     maxn = dp[i][j];
31                 }
32             }
33         }
34         for (int i = 1;i <= m;i++)
35             if (dp[n][i] > res)
36             {
37                 res = dp[n][i];
38             }
39         printf("%d\n",res);
40         res = 0;
41         if (T != 1)
42             printf("\n");
43     }
44     return 0;
45 }

 

posted @ 2019-08-20 20:54  IAT14  阅读(145)  评论(0编辑  收藏  举报