POJ 1080 Human Gene Functions(LCS變形)
阿新 • • 發佈:2020-08-26
題目大意
給兩個不同的字串,比較其相似度,你可以在字元之間插入'-',不同字元之間的相似度參考題目中的表格。
解題思路
這題主要還是考驗對LCS的理解。定義dp[i][j]表示第一個串s1長度為i時與第二個串s2長度為j時的相似度(注意不算'-')。
我們在求dp[i][j]的時候,分三種情況:
1.s1[i]與s2[j]相匹配,那麼結果就是直接長度為i-1的串s1與長度為j-1的串s2的匹配結果加上這兩個字元的匹配度。
2.如果s1[i]與s2[j]之前的某個字元匹配了,那麼s2[j]就只能和'-'匹配了。
3.如果s1[i]之前的某個字元與s2[j]的某個字元匹配了,那麼s1[i]就只能和'-'匹配了。
dp的狀態轉移方程與LCS相似,注意dp[i][0]與dp[0][j]的初值,具體看程式碼吧。
程式碼
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<sstream> #include<iostream> #include<algorithm> #define endl '\n' #define clr(arr,b) memset(arr, b, sizeof(arr)) #define IOS ios::sync_with_stdio(false) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; typedef pair<ll, int> Pll; const double pi = acos(-1.0); const double eps = 1e-8; const ll MOD = 1e9+7; const int INF = 0x3f3f3f3f; const int maxn = 1e2+10; const int maxm = 2e2+10; int l1, l2, dp[maxn][maxn], mp[maxn][maxn], skp[maxn]; char s1[maxn], s2[maxn]; int main() { mp['A']['A'] = mp['C']['C'] = mp['G']['G'] = mp['T']['T'] = 5; mp['A']['C'] = mp['C']['A'] = -1; mp['A']['G'] = mp['G']['A'] = -2; mp['A']['T'] = mp['T']['A'] = -1; mp['C']['G'] = mp['G']['C'] = -3; mp['C']['T'] = mp['T']['C'] = -2; mp['G']['T'] = mp['T']['G'] = -2; skp['A'] = -3; skp['C'] = -4, skp['G'] = -2, skp['T'] = -1; int t; cin >> t; while(t--) { cin >> l1 >> (s1+1) >> l2 >> (s2+1); for (int i = 1; i<=l1; ++i) dp[i][0] = dp[i-1][0]+skp[s1[i]]; for (int i = 1; i<=l2; ++i) dp[0][i] = dp[0][i-1]+skp[s2[i]]; for (int i = 1; i<=l1; ++i) for (int j = 1; j<=l2; ++j) dp[i][j] = max(dp[i-1][j-1]+mp[s1[i]][s2[j]], max(dp[i-1][j]+skp[s1[i]], dp[i][j-1]+skp[s2[j]])); cout << dp[l1][l2] << endl; } return 0; }