題目
題目分析
對動態規劃題目的理解不是特別深,所以看了別人的部落格進行學習,給出部落格地址交錯匹配部落格,說的非常好也非常詳細,但是預先處理寫的不是很好,我用自己想到的思路寫了出來,清晰明白一點。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2005;int a[maxn],b[maxn];int dp1[maxn][maxn],dp2[maxn][maxn],f[maxn][maxn];void init(int n,int m){ memset(dp1, 0, sizeof(dp1)); memset(dp2, 0, sizeof(dp2)); for(int i = 1; i <= n; i++) //dp1儲存a列前i個數和b列前j個元素中,最靠近j的位置且等於a[i]的元素位置 { for(int j = 2; j <= m; j++) { if(a[i] == b[j-1]) dp1[i][j] = j-1; else dp1[i][j] = dp1[i][j-1]; } } for(int j = 1; j <= m; j++) //dp2儲存a列前i個數和b列前j個元素中,最靠近i的位置且等於b[j]的元素位置 { for(int i = 2; i <= n; i++) { if(b[j] == a[i-1]) dp2[i][j] = i-1; else dp2[i][j] = dp2[i-1][j]; } }}int main(){ int n,m; while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int j = 1; j <= m; j++) scanf("%d", &b[j]); init(n, m); memset(f, 0, sizeof(f)); for(int i = 2; i <= n; i++) { for(int j = 2; j <= m; j++) { f[i][j] = f[i-1][j-1]; //i和j都不參加匹配 f[i][j] = max(f[i][j], f[i-1][j]); //i不參加匹配 f[i][j] = max(f[i][j], f[i][j-1]); //j不參加匹配 if(a[i] != b[j]) //前面有能匹配的數,同時找到的是離i,j最近的,因為這樣一定是最優的 { int ip = dp2[i][j],jp = dp1[i][j]; if(ip && jp) f[i][j] = max(f[i][j], f[ip-1][jp-1] + 2); } } } printf("%d\n", f[n][m]); } return 0;}