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]); } }
大神的代码写的就是漂亮,不要怪罪我吧。