洛谷【P1140】相似基因

时间:2023-03-10 06:24:31
洛谷【P1140】相似基因

浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html

题目传送门:https://www.luogu.org/problemnew/show/P1140

以已经匹配完了的长度为阶段,\(f[i][j]\)为状态,表示已匹配了第一个串的\(i\)个,第二个串的前\(j\)个。

转移则是\(f[i][j]=max(f[i][j],f[i-1][j-1]+cost[a_i][b_j],f[i-1][j]+cost[a_i]['-'],f[i][j-1]+cost[b_j]['-'])\)

\(cost[s1][s2]\)表示这俩字符的匹配贡献。

时间复杂度:\(O(n^2)\)

空间复杂度:\(O(n^2)\)

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int n,m;
int p[105];
int f[105][105];
char a[105],b[105];
int cost[5][5]={
5,-1,-2,-1,-3,
-1,5,-3,-2,-4,
-2,-3,5,-2,-2,
-1,-2,-2,5,-1,
-3,-4,-2,-1,0
}; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} int main() {
p['A']=0,p['C']=1,p['G']=2,p['T']=3,p['-']=4;
n=read(),scanf("%s",a+1);
m=read(),scanf("%s",b+1);
memset(f,-63,sizeof(f));f[0][0]=0;
for(int i=1;i<=n;i++)
f[i][0]=f[i-1][0]+cost[p[(int)a[i]]][p['-']];
for(int i=1;i<=m;i++)
f[0][i]=f[0][i-1]+cost[p[(int)b[i]]][p['-']];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
int A=a[i],B=b[j];
f[i][j]=max(f[i][j],f[i-1][j-1]+cost[p[A]][p[B]]);
f[i][j]=max(f[i][j],f[i-1][j]+cost[p[A]][p['-']]);
f[i][j]=max(f[i][j],f[i][j-1]+cost[p[B]][p['-']]);
}
printf("%d\n",f[n][m]);
return 0;
}