HDU 1423

最长公共上升子序列,仔细分析下会有O(N2)的算法。

#include <cstdio>

int a[500], b[500], A, B;
int _dp[501][501];
#define dp(x,y)    _dp[(x)+1][(y)+1]

#define max(a,b) ((a)>(b)?(a):(b))

int main(void)
{
//    freopen("hdu1423.txt", "r", stdin);
    int T;
    for(scanf("%d", &T); T; ) {
        int ans = 0;
        scanf("%d", &A); for(int i=0; i<A; ++i) scanf("%d", &a[i]);
        scanf("%d", &B); for(int i=0; i<B; ++i) scanf("%d", &b[i]);
        for(int i=0; i<A; ++i) {
            int m = 0;
            for(int j=0; j<B; ++j) {
                dp(i,j)= max(dp(i,j-1), dp(i-1, j));
                if (b[j] < a[i] && dp(i,j) > dp(i,m))
                    m = j;
                else if (b[j] == a[i] && dp(i,j) < dp(i,m) + 1) {
                    dp(i,j) = dp(i,m) + 1;
                    if (ans < dp(i,j)) ans = dp(i,j);
                }
            }
        }
        printf("%d
", ans);
        if (--T) putchar('
');
    }
    return 0;
}
10745680 2014-05-15 18:29:46 Accepted 1423 0MS 312K 771 B G++

2014/5/17更新:

其实之前题解的转移有问题,dp[i][j]的定义应该是A数组前i个数中、B数组精确到第j个数结尾的最大公共上升子序列。所以就不能有dp[i][j-1]这个转移,因为numB[j-1] > numB[j](仔细想一想)。

#include <cstdio>

int a[500], b[500], A, B;
int _dp[501][501];
#define dp(x,y)    _dp[(x)+1][(y)+1]

int main(void)
{
//    freopen("hdu1423.txt", "r", stdin);
    int T;
    for(scanf("%d", &T); T; ) {
        scanf("%d", &A); for(int i=0; i<A; ++i) scanf("%d", &a[i]);
        scanf("%d", &B); for(int i=0; i<B; ++i) scanf("%d", &b[i]);
        for(int i=0; i<A; ++i) {
            int k = 0;
            for(int j=0; j<B; ++j) {
                dp(i,j)= dp(i-1,j);
                if (b[j] < a[i] && dp(i-1,j) > k) k = dp(i-1,j);
                else if (b[j] == a[i] && dp(i,j) < k + 1) dp(i,j) = k + 1;
            }
        }
        int ans = 0;
        for(int j=0; j<B; ++j)
            if (ans < dp(A-1,j)) ans = dp(A-1,j);
        printf("%d
", ans);
        if (--T) putchar('
');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/e0e1e/p/hdu_1423.html