UVA1625Color Lenth(DP+LCS变形 未AC)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/C
紫书P276
res[i][j]表示第一个序列移动i个,第二个序列移动j个之后有几个已经出现但尚未结束,dp[i][j]表示第一个序列移动i个,第二个序列移动j个之后的总长度
dp[i][j] = min(dp[i - 1][j],dp[i][j - 1]) + res[i][j]
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int MAX = 5000 + 10; 7 const int INF = 0x3f3f3f3f; 8 char str1[MAX],str2[MAX]; 9 int dp[MAX][MAX],res[MAX][MAX]; 10 int start1[30],End1[30],start2[30],End2[30],vis[30]; 11 int n,m; 12 int main() 13 { 14 int tase; 15 scanf("%d", &tase); 16 while(tase--) 17 { 18 scanf("%s%s", str1 + 1,str2 + 1); 19 n = strlen(str1 + 1); 20 m = strlen(str2 + 1); 21 memset(vis, 0, sizeof(vis)); 22 memset(End1, -1, sizeof(End1)); 23 memset(End2, -1, sizeof(End2)); 24 for(int i = 0; i < 27; i++) 25 start1[i] = start2[i] = INF; 26 for(int i = 1; i <= n; i++) 27 { 28 if(start1[str1[i] - 'A'] == INF) 29 start1[str1[i] - 'A'] = i; 30 End1[str1[i] - 'A'] = i; 31 } 32 for(int i = 1; i <= m; i++) 33 { 34 if(start2[str2[i] - 'A'] == INF) 35 start2[str2[i] - 'A'] = i ; 36 End2[str2[i] - 'A'] = i; 37 } 38 39 memset(res, 0, sizeof(res)); 40 for(int i = 0; i <= n; i++) 41 { 42 for(int j = 0; j <= m; j++) 43 { 44 int cnt = 0; 45 for(int k = 0; k < 26; k++) 46 { 47 if(start1[k] == INF && start2[k] == INF) 48 continue; 49 if(start1[k] > i && start2[k] > j) 50 continue; 51 if(End1[k] <= i && End2[k] <= j) 52 continue; 53 cnt++; 54 } 55 res[i][j] = cnt; 56 } 57 } 58 59 dp[0][0] = 0; 60 for(int i = 1; i <= m ; i++) 61 dp[0][i] = dp[0][i - 1] + res[0][i]; 62 for(int j = 1; j <= n; j++) 63 dp[j][0] = dp[j - 1][0] + res[j][0]; 64 for(int i = 1; i <= n; i++) 65 { 66 for(int j = 1; j <= m; j++) 67 { 68 dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + res[i][j]; 69 } 70 } 71 72 printf("%d\n", dp[n][m]); 73 74 } 75 76 return 0; 77 }