Uva--1625(动规)
2014-09-05 20:56:52
题目老长:放链接
思路:第二版小白书例题,参考了书上的思路。事先预处理出每个颜色在两个序列中的开始和结束位置,用dp[i][j]表示:第一个串用了前 i 个字符,第二个串用了前 j 个字符组成的串的最优解,每次递推都要用O(1)的时间来计算“有多少个颜色已经开始但尚未结束。”
1 /************************************************************************* 2 > File Name: Uva1625.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 05 Sep 2014 02:00:29 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 const int INF = 1 << 28; 16 17 int T,l1,l2; 18 int dp[5005][5005]; 19 int st1[27],st2[27],ed1[27],ed2[27]; 20 char s1[5005],s2[5005]; 21 22 int main(){ 23 scanf("%d",&T); 24 while(T--){ 25 scanf("%s%s",s1 + 1,s2 + 1); 26 l1 = strlen(s1 + 1); 27 l2 = strlen(s2 + 1); 28 for(int i = 0; i < 27; ++i){ 29 st1[i] = st2[i] = INF; 30 ed1[i] = ed2[i] = 0; 31 } 32 for(int i = 1; i <= l1; ++i){ 33 int id = s1[i] - 'A'; 34 if(st1[id] == INF) st1[id] = i; 35 ed1[id] = i; 36 } 37 for(int i = 1; i <= l2; ++i){ 38 int id = s2[i] - 'A'; 39 if(st2[id] == INF) st2[id] = i; 40 ed2[id] = i; 41 } 42 for(int i = 0; i <= l1; ++i){ 43 for(int j = 0; j <= l2; ++j){ 44 //dp[i][j] <- dp[i - 1][j] or dp[i][j - 1]; 45 int res = INF,cnt = 0; 46 for(int k = 0; k < 26; ++k) 47 if((i >= st1[k] || j >= st2[k]) && (i < ed1[k] || j < ed2[k])) 48 ++cnt; 49 if(i > 0) res = min(res,dp[i - 1][j]); 50 if(j > 0) res = min(res,dp[i][j - 1]); 51 dp[i][j] = (res == INF ? 0 : res) + cnt; 52 } 53 } 54 printf("%d\n",dp[l1][l2]); 55 } 56 return 0; 57 } 58