HDU 1423 - Greatest Common Increasing Subsequence
最长公共上升子序列,仔细分析下会有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\n", ans); if (--T) putchar('\n'); } 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\n", ans); if (--T) putchar('\n'); } return 0; }
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。