洛谷 P1140 相似基因
阿新 • • 發佈:2018-12-23
https://www.luogu.org/problemnew/show/P1140
根據題目給出的鹼基配對錶,發現:
1.兩基因相同時產生+5,其餘都是負數。
2.任意兩個不同基因相配,直接配要好於分別與空鹼基配。但是兩基因不滿足上1點的長度不同,所以必須有一些基因與空鹼基相配。
設f(i,j)表示第一個基因前i個和第二個基因前j個相配的最大相似度
邊界為f(0,j)=第二個基因前j個分別與空基因相配的相似度
f(i,0)=第一個基因前i個分別與空基因相配的相似度
f(i,j)= f(i-1,j-1)+5 ,a[i]==b[j]
max( f(i-1,j)+a[i]配空 ,f(i,j-1)+b[j]配空 ,f(i-1,j-1)+a[i]配b[j] ) ,a[i]!=b[j]
#include<bits/stdc++.h> using namespace std; int n,m,d[105][105]; char a[105],b[105]; map<char,int>score; int score2[300][300]; void init() { score['T']=-1; score['G']=-2; score['A']=-3; score['C']=-4; score2['A']['C']=-1; score2['A']['T']=-1; score2['A']['G']=-2; score2['T']['C']=-2; score2['T']['G']=-2; score2['C']['G']=-3; } int main() { freopen("input.in","r",stdin); scanf("%d%s%d%s",&n,a+1,&m,b+1); init(); int sum=0; for(int j=1;j<=m;j++) { sum+=score[b[j]]; d[0][j]=sum; } sum=0; for(int j=1;j<=n;j++) { sum+=score[a[j]]; d[j][0]=sum; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i]==b[j])d[i][j]=d[i-1][j-1]+5; else d[i][j]=max(d[i-1][j-1]+min(score2[a[i]][b[j]],score2[b[j]][a[i]]),max(d[i-1][j]+score[a[i]],d[i][j-1]+score[b[j]])); } } cout<<d[n][m]<<endl; return 0; }