LCS

Longest Common Sequence

两个串,求最大公共子序的长度,这是一个经典的问题。 动态规划的解法是:

f(i,j)=max(f(i-1,j),f(i,j-1), f(i-1,j-1)+(a[i]==b[j]?));

2012 gcj Round 1C的第三题Box Factory就是一个LCS问题的变形。

http://code.google.com/codejam/contest/1781488/dashboard#s=p2

不同的是这里f(i-1,j-1)这一项比较复杂。需要i,j一直向0搜索,然后得到一个最大值。

for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (a[i].type == b[j].type) {
                LL totalA = a[i].count;
                LL totalB = b[j].count;
                int prevA = i - 1;
                int prevB = j - 1;
                while (true) {
                    dp[i][j] = max(dp[i][j], dp[prevA][prevB] + min(totalA, totalB));
                    int state = (totalA < totalB) ? -1 : (totalA == totalB ? 0 : 1);
                    bool finished = false;
                    if (state <= 0) {
                        while (prevA > 0 && a[prevA].type != a[i].type) {
                            --prevA;
                        }
                        if (prevA == 0) {
                            finished = true;
                        } else {
                            totalA += a[prevA].count;
                            --prevA;
                        }
                    }
                    if (state >= 0) {
                        while (prevB > 0 && b[prevB].type != b[j].type) {
                            --prevB;
                        }
                        if (prevB == 0) {
                            finished = true;
                        } else {
                            totalB += b[prevB].count;
                            --prevB;
                        }
                    }
                    if (finished) {
                        break;
                    }
                }
            } else {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }

大神的代码写的就是漂亮,不要怪罪我吧。

posted @ 2012-08-22 10:20  xxx's blog  阅读(210)  评论(0编辑  收藏  举报