1. 程式人生 > >洛谷P1140 相似基因【線性dp】

洛谷P1140 相似基因【線性dp】

blank 題目 pro cstring lib color algorithm const href

題目:https://www.luogu.org/problemnew/show/P1140

題意:

給定兩串基因串(只包含ATCG),在其中插入任意個‘-’使得他們匹配。(所以一共是5種字符)

這5種字符兩兩之間有一個匹配數值,要求使這兩個字符串的匹配值之和最大。

思路:

dp[i][j]表示匹配了s1中前i個字符和s2中前j個字符的最大匹配值。

完成s1[i]與s2[j]的匹配只有三種可能。

1.s1[i]之前已經匹配好,s2[j]配‘-’。即dp[i][j] = dp[i][j-1]+sco[s2[j]][‘-‘]

2.s2[j]之前已經匹配好,s1[i]配‘-’。即d[i][j] = dp[i-1][j]+sco[s1[i]][‘-‘]

3.s1[i]配s2[j]。即dp[i][j] = dp[i - 1][j - 1] + sco[s1[i]][s2[j]]

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<map>
 4 #include<set>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<cmath> 
 9 #include<stack>
10 #include<queue>
11
#include<iostream> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 const int sco[5][5] = 19 { 20 {5, -1, -2, -1, -3}, 21 {-1, 5, -3, -2, -4}, 22 {-2, -3, 5, -2, -2}, 23 {-1, -2, -2, 5, -1}, 24 {-3
, -4, -2, -1, 0}, 25 }; 26 const int maxn = 105; 27 int len1, len2; 28 char s1[maxn], s2[maxn]; 29 int dp[maxn][maxn]; 30 31 int main() 32 { 33 scanf("%d %s", &len1, s1 + 1); 34 scanf("%d %s", &len2, s2 + 1); 35 map<char, int>mp; 36 mp[A] = 0;mp[C] = 1;mp[G] = 2; mp[T] = 3; 37 for(int i = 0; i <= len1; i++){ 38 for(int j = 0; j <= len2; j++){ 39 dp[i][j] = -2e8; 40 } 41 } 42 43 dp[0][0] = 0; 44 for(int i = 1; i <= len1; i++){ 45 dp[i][0] = dp[i - 1][0] + sco[mp[s1[i]]][4]; 46 } 47 for(int i = 1; i <= len2; i++){ 48 dp[0][i] = dp[0][i - 1] + sco[mp[s2[i]]][4]; 49 } 50 for(int i = 1; i <= len1; i++){ 51 for(int j = 1; j <= len2; j++){ 52 dp[i][j] = max(dp[i][j], dp[i][j - 1] + sco[mp[s2[j]]][4]); 53 dp[i][j] = max(dp[i][j], dp[i - 1][j] + sco[mp[s1[i]]][4]); 54 dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + sco[mp[s1[i]]][mp[s2[j]]]); 55 } 56 } 57 printf("%d\n", dp[len1][len2]); 58 return 0; 59 }

洛谷P1140 相似基因【線性dp】