题目: http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1305
这个题就是一个类似公共子串的dp,但是加了权值,其实还是很简单。
当匹配时相似程度是5,不匹配是-4,添加空隙是-7。那么dp[i][j]的值就来自于三个方式:
1、在s2[j]后添加空隙,那么相似程度就是dp[i][j-1] - 7
2、在s1[i]后添加空隙,那么相似程度就是dp[i-1][j] - 7
3、直接拿s1[i]和s2[j]匹配,如果匹配相似程度就是dp[i-1][j-1] + 5,如果不匹配相似程度就是dp[i-1][j-1] - 4
最后找一下字典序最小的,就是这样了。。。就是代码写的搓了一点。
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 5 int dp[110][110]; 6 char s1[110], s2[1010][110]; 7 8 int main() 9 { 10 int t, ans = 0, x; 11 scanf("%s %d", s1, &t); 12 int n = strlen(s1); 13 for(int item = 0; item < t; item++) 14 { 15 scanf("%s", s2[item]); 16 int m = strlen(s2[item]); 17 dp[0][0] = 0; 18 for(int i = 1; i <= n; i++) 19 dp[i][0] = dp[i-1][0] - 7; 20 for(int j = 1; j <= m; j++) 21 dp[0][j] = dp[0][j-1] - 7; 22 for(int i = 1; i <= n; i++) 23 { 24 for(int j = 1; j <= m; j++) 25 { 26 dp[i][j] = std::max(std::max(dp[i-1][j] - 7, dp[i][j-1] - 7), dp[i-1][j-1] + (s1[i-1] == s2[item][j-1] ? 5 : -4)); 27 } 28 } 29 if(dp[n][m] > ans || (dp[n][m] == ans && strcmp(s2[x], s2[item]) > 0)) 30 { 31 ans = dp[n][m]; 32 x = item; 33 } 34 } 35 printf("%d %s ", ans, s2[x]); 36 return 0; 37 }