码迷,mamicode.com
首页 > 其他好文 > 详细

CH5101 LCIS【线性dp】

时间:2018-10-04 10:02:22      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:hide   none   algorithm   set   输入   iostream   cout   clu   space   

5101 LCIS 0x50「动态规划」例题

描述

熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目。小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们研究最长公共上升子序列了。
小沐沐说,对于两个数列A和B,如果它们都包含一段位置不一定连续的数,且数值是严格递增的,那么称这一段数是两个数列的公共上升子序列,而所有的公共上升子序列中最长的就是最长公共上升子序列了。
奶牛半懂不懂,小沐沐要你来告诉奶牛什么是最长公共上升子序列。不过,只要告诉奶牛它的长度就可以了。数列A和B的长度均不超过3000。

输入格式

第一行N,表示A,B的长度。
第二行,串A。
第三行,串B。

输出格式

输出长度。

样例输入

4
2 2 1 3
2 1 2 3

样例输出

2

数据范围与约定

  • 1<=N<=3000,A,B中的数字不超过2^31-1

Contest Hunter - 信息学自助比赛平台

 

LIS与LCS问题的结合

dp[i][j]表示A1-Ai和B1-Bj中以Bj为结尾的LCIS的长度

那么当Ai != Bj 时 显然dp[i][j] = dp[i-1][j]

当Ai == Bj时 判断1-j中是否有Bk < Bj 取所有可能解的最大值加一

找k时可以for循环跑 那么总的复杂度是n^3

优化的算法是对于每一个i A[i]都没有变化 每次j增加 可能解的数量是递增的

每一次都记录当前j的最大可能解就可用于下一次更新了

 

“在实现状态转移方程时,要注意观察决策集合的范围随着状态的变化情况。对于“决策集合中的元素只增多不减少的”的情景,就可以像本题一样维护一个变量来记录决策集合的当前信息,避免重复扫描”

 

很坑的是第三组数据好像个数有问题还是怎么的?反正我输出时多了一个\n就WA,去掉\n就过了

n^2算法

 1 //#include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 
 8 using namespace std;
 9 typedef long long int LL;
10 
11 const int maxn = 3005;
12 int A[maxn], B[maxn];
13 int n;
14 int dp[maxn][maxn];
15 
16 int main()
17 {
18         scanf("%d", &n);
19         for(int i = 1; i <= n; i++)
20             scanf("%d", &A[i]);
21         for(int i = 1; i <= n; i++)
22             scanf("%d", &B[i]);
23 
24         //memset(dp, 0, sizeof(dp));
25         for(int i = 1; i <= n; i++){
26             int val = 0;
27             for(int j = 1; j <= n; j++){
28                 if(A[i] == B[j]){
29                     dp[i][j] = val + 1;
30                 }
31                 else{
32                     dp[i][j] = dp[i - 1][j];
33                 }
34                 if(B[j] < A[i]) val = max(val, dp[i - 1][j]);
35             }
36         }
37 
38         int ans = 0;
39         for(int i = 1; i <= n; i++){
40             ans = max(ans, dp[n][i]);
41         }
42         //cout<<endl;
43         printf("%d", ans);
44         //scanf("%d", &n);
45     return 0;
46 }

n^3算法

技术分享图片
 1 //#include <bits/stdc++.h>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 #include<cstring>
 7 
 8 using namespace std;
 9 typedef long long int LL;
10 
11 const int maxn = 3005;
12 int A[maxn], B[maxn];
13 int n;
14 int dp[maxn][maxn];
15 
16 int main()
17 {
18         scanf("%d", &n);
19         for(int i = 1; i <= n; i++)
20             scanf("%d", &A[i]);
21         for(int i = 1; i <= n; i++)
22             scanf("%d", &B[i]);
23 
24         //memset(dp, 0, sizeof(dp));
25         for(int i = 1; i <= n; i++){
26             for(int j = 1; j <= n; j++){
27                 if(A[i] == B[j]){
28                     for(int k = 0; k < j; k++){
29                         if(B[k] < A[i])
30                             dp[i][j] = max(dp[i - 1][k] + 1, dp[i][j]);
31                     }
32                 }
33                 else{
34                     dp[i][j] = dp[i - 1][j];
35                 }
36             }
37         }
38 
39         int ans = 0;
40         for(int i = 1; i <= n; i++){
41             ans = max(ans, dp[n][i]);
42         }
43         //cout<<endl;
44         printf("%d", ans);
45         //scanf("%d", &n);
46     return 0;
47 }
View Code

 

CH5101 LCIS【线性dp】

标签:hide   none   algorithm   set   输入   iostream   cout   clu   space   

原文地址:https://www.cnblogs.com/wyboooo/p/9739863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!