首页 > 代码库 > HDU 5904 LCIS DP

HDU 5904 LCIS DP

http://acm.hdu.edu.cn/showproblem.php?pid=5904

给定两个序列,要求算出其最长的公共上升子序列,

并且这个子序列公差是1.

考虑dp

dpa[val]表示在a数组中,以val这个数字结尾,最长上升1的子序列。dpa[val] = dpa[val - 1] + 1

同理dpb[val]

然后,对于每个相同的数字,需要取min(dpa[val], dpb[val])即可。

如果dpa[5] = 3是这个序列,3 4 5

然后dpb[5] = 5是这个序列 1 2 3 4 5

那么公共部分就是他们的最小值。

技术分享
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define inf (0x3f3f3f3f)typedef long long int LL;#include <iostream>#include <sstream>#include <vector>#include <set>#include <map>#include <queue>#include <string>const int maxn = 100000 + 20;int a[maxn];int b[maxn];int dpa[maxn];int dpb[maxn];void work() {    memset(dpa, 0, sizeof dpa);    memset(dpb, 0, sizeof dpb);    int n, m;    int mx = -inf;    scanf("%d%d", &n, &m);    for (int i = 1; i <= n; ++i) {        scanf("%d", &a[i]);        mx = max(mx, a[i]);    }    int mx2 = -inf;    for (int i = 1; i <= m; ++i) {        scanf("%d", &b[i]);        mx2 = max(mx2, b[i]);    }    mx = min(mx, mx2);    dpa[a[1]] = 1;    for (int i = 2; i <= n; ++i) {        dpa[a[i]] = dpa[a[i] - 1] + 1;    }    dpb[b[1]] = 1;    for (int i = 2; i <= m; ++i) {        dpb[b[i]] = dpb[b[i] - 1] + 1;    }    int ans = -inf;    for (int i = 1; i <= mx; ++i) {        ans = max(ans, min(dpa[i], dpb[i]));    }    printf("%d\n", ans);    return ;}int main() {#ifdef local    freopen("data.txt","r",stdin);#endif    int t;    scanf("%d", &t);    while (t--) work();    return 0;}
View Code

 

HDU 5904 LCIS DP