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 }
心之所动 且就随缘去吧