P1140 相似基因
https://www.luogu.com.cn/problem/P1140
想随便找一道DP自己做,练练手,于是又找了一个生物题。
结果emm看着不着边际的输出自闭了。
后来翻了翻题解,发现自己的状态转移方程是对的,但是没有处理边界情况(i=0,j=0)。
还是太蒻了。
顺便吐槽:空碱基是什么鬼东西。。
这道题其实也就把字符串转化一下,然后把对应关系用二维数组搞搞,
设f[i][j]是碱基序列s1以i、s2以j结尾的最优方案,
显然有f[i][j]=max(f[i-1][j-1]+m[s1[i]][s2[j]],f[i][j-1]+m[0][s2[j]],f[i-1][j]+m[s1[i]][0])
其中m[i][j]表示对应的相似度
这里对i 1...n1, j 1...n2填表就行,关键是...
f[i][0]和f[0][j]咱不知道啊
它不能用上面的方程推出来啊
所以得
for(int i=1;i<=n1;i++)f[i][0]=f[i-1][0]+m[s1[i]][0];
for(int j=1;j<=n2;j++)f[0][j]=f[0][j-1]+m[0][s2[j]];啊。
就完事了。
就完事了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 string sx,sy; 4 int n1,n2,s1[102],s2[102],f[102][102]; 5 int m[5][5]={ 6 {0,-3,-4,-2,-1}, 7 {-3,5,-1,-2,-1}, 8 {-4,-1,5,-3,-2}, 9 {-2,-2,-3,5,-2}, 10 {-1,-1,-2,-2,5}, 11 }; 12 int get(char s){ 13 if(s=='A')return 1; 14 if(s=='C')return 2; 15 if(s=='G')return 3; 16 if(s=='T')return 4; 17 } 18 int main(){ 19 cin>>n1>>sx>>n2>>sy; 20 for(int i=0;i<n1;i++)s1[i+1]=get(sx[i]); 21 for(int i=0;i<n2;i++)s2[i+1]=get(sy[i]); 22 f[0][0]=0; 23 for(int i=1;i<=n1;i++)f[i][0]=f[i-1][0]+m[s1[i]][0]; 24 for(int j=1;j<=n2;j++)f[0][j]=f[0][j-1]+m[0][s2[j]]; 25 for(int i=1;i<=n1;i++) 26 for(int j=1;j<=n2;j++) 27 f[i][j]=max(f[i-1][j-1]+m[s1[i]][s2[j]],max(f[i][j-1]+m[0][s2[j]],f[i-1][j]+m[s1[i]][0])); 28 cout<<f[n1][n2]; 29 } 30