#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
map<string,int> dicm;//字典
void myinit()//初始化字典
{
dicm.insert(make_pair("AA",5));
dicm.insert(make_pair("AC",-1));
dicm.insert(make_pair("AG",-2));
dicm.insert(make_pair("AT",-1));
dicm.insert(make_pair("A-",-3));
dicm.insert(make_pair("CA",-1));
dicm.insert(make_pair("CC",5));
dicm.insert(make_pair("CG",-3));
dicm.insert(make_pair("CT",-2));
dicm.insert(make_pair("C-",-4));
dicm.insert(make_pair("GA",-2));
dicm.insert(make_pair("GC",-3));
dicm.insert(make_pair("GG",5));
dicm.insert(make_pair("GT",-2));
dicm.insert(make_pair("G-",-2));
dicm.insert(make_pair("TA",-1));
dicm.insert(make_pair("TC",-2));
dicm.insert(make_pair("TG",-2));
dicm.insert(make_pair("TT",5));
dicm.insert(make_pair("T-",-1));
dicm.insert(make_pair("-A",-3));
dicm.insert(make_pair("-C",-4));
dicm.insert(make_pair("-G",-2));
dicm.insert(make_pair("-T",-1));
}
int simility(string s1,string s2)//求字符串s1与s2的相似度(常规解法--类似于求最大公共序列)
{
string s;
int sum = 0;
if(s1.size() == 0)
{
for(int i = 0; i < s2.size(); i++)
{
s = "-";
s += s2[i];
sum += dicm[s];
}
return sum;
}
else if(s2.size() == 0)
{
for(int i = 0; i < s1.size(); i++)
{
s = s1[i];
s += "-";
sum += dicm[s];
}
return sum;
}
//case 1:
int result1;
{
s = s1[s1.size()-1];
s += s2[s2.size()-1];
string ts1 = s1,ts2 = s2;
ts1.erase(ts1.size()-1);
ts2.erase(ts2.size()-1);
result1 = simility(ts1,ts2)+dicm[s];
}
//case 2:
int result2;
{
s = s1[s1.size()-1];
s += "-";
string ts1 = s1,ts2 = s2;
ts1.erase(ts1.size()-1);
result2 = simility(ts1,ts2)+dicm[s];
}
//case 3:
int result3;
{
s = "-";
s += s2[s2.size()-1];
string ts1 = s1,ts2 = s2;
ts2.erase(ts2.size()-1);
result3 = simility(ts1,ts2)+dicm[s];
}
return max(result1,max(result2,result3));
}
int r[102][102];
int len1,len2;// 1 <= len1,len2 <= 100
int simility2(string s1,string s2)//求字符串s1与s2的相似度(动态规划解法)
{
for(int i = 0; i < len1; i++)
{
for(int j = 0; j < len2; j++)
{
string s;
int result1;//case 1
{
s = s1[i];
s += s2[j];
if(i-1 >= 0 && j-1 >= 0)
result1 = r[i-1][j-1] + dicm[s];
else if(i-1 < 0)
{
if(j-1 >= 0)
{
int sum = 0;
string ts;
for(int k = 0; k <= j-1; k++)
{
ts = '-';
ts += s2[k];
sum += dicm[ts];
}
result1 = sum + dicm[s];
}
else
result1 = dicm[s];
}
else if(j-1 < 0)
{
int sum = 0;
string ts;
for(int k = 0; k <= i-1; k++)
{
ts = s1[k];
ts += '-';
sum += dicm[ts];
}
result1 = sum + dicm[s];
}
}
int result2;//case 2
{
s = '-';
s += s2[j];
if(j-1 >= 0)
result2 = r[i][j-1] + dicm[s];
else// j-1 < 0
{
int sum = 0;
string ts;
for(int k = 0; k <= i; k++)
{
ts = s1[k];
ts += '-';
sum += dicm[ts];
}
result2 = sum + dicm[s];
}
}
int result3;//case3
{
s = s1[i];
s += '-';
if(i-1 >= 0)
result3 = r[i-1][j] + dicm[s];
else// i-1 < 0
{
int sum = 0;
string ts;
for(int k = 0; k <= j; k++)
{
ts = '-';
ts += s2[k];
sum += dicm[ts];
}
result3 = sum + dicm[s];
}
}
r[i][j] = max(result1,max(result2,result3));
}
}
return r[len1-1][len2-1];
}
int main()
{
freopen("in.txt","r",stdin);
myinit();
int t; // 1 <= t <= 10
string s1,s2;
cin>>t;
while(t--)
{
cin>>len1>>s1>>len2>>s2;
cout<<"sim1 = "<<simility(s1,s2)
<<" sim2 = "<<simility2(s1,s2)<<endl;
}
return 1;
}
测试用例:
7
2 AG
1 G
1 A
1 G
2 GT
1 A
2 AG
2 GT
3 AGT
3 GTT
7 AGTGATG
5 GTTAG
7 AGCTATT
9 AGCTTTAAA
动态规划算法思想:
1,很明显此题满足最优子结构性质
2,
index of s1 | 0 | i | ||||||||||||||||||
s1 | ||||||||||||||||||||
index of s2 | 0 | j | ||||||||||||||||||
s2 |
最大匹配度为:
r[ i ] [ j ] = max( r(s1[0 ... i-1] , s2[0... j-1]) + dicm[ s1[i] s2[j] ],
r( s1[0 ... i] , s2[0... j-1] ) + dicm[ - s2[j] ],
r( s1[0 ... i-1] , s2[0... j ] ) + dicm[ s1[i] - ]
),其中 0 <= i <= s1.size()-1, 0 <= j <= s2.size() - 1; 注意边界情况,即i - 1 < 0 , j - 1< 0 的情况
最大匹配度即为r[s1.size() - 1] [ s2.size() - 1]