【dp】相似基因
程序员文章站
2022-07-13 12:07:01
...
大致思路:
dfs也写了dp也写了然后发现题读错了。。。。所以比赛的时候一定要先把题多读两遍每个句子都给它读懂!!!!
这里两个字符串都可以加入空碱基!
这道题用dp做,难点在哪里呢?
我认为难点在于dp的含义设定:
含义中那个“不计算空碱基”的设定真的是绝了,不然真的,写不出状态转移方程出来的(鬼知道能加多少个空碱基)
这个状态转移很类似于两个字符串求公共子序列。
真的%%%%%%。希望比赛的时候我能有点这种神灵感,脑洞大开,写出完美状态转移方程!!!!!!!
代码(copy):
using namespace std;
int l1,l2,a[110],b[110];
char s1[110],s2[110];
int f[110][110];
int p[6][6]= //初始化碱基之间的配对值
{
{0},
{0,5,-1,-2,-1,-3},
{0,-1,5,-3,-2,-4},
{0,-2,-3,5,-2,-2},
{0,-1,-2,-2,5,-1},
{0,-3,-4,-2,-1,0}
};
int fuck(char c)//将字符转化为序号
{
if(c=='A') return 1;
if(c=='C') return 2;
if(c=='G') return 3;
return 4;
}
int main()
{
//freopen("acgt.in","r",stdin);//文件输入输出
//freopen("acgt.out","w",stdout);//同上
int t,i,j;
scanf("%d%s%d%s",&l1,s1+1,&l2,s2+1);//输入(输入完后s1,s2的第一个字符在s[1]的位置)
for(i=1;i<=l1;i++)
for(j=1;j<=l2;j++)
f[i][j]=INT_MIN;//将f数组初始化为一个很小的值
for(i=1;i<=l1;i++)
a[i]=fuck(s1[i]);//将s1中的字符转化为序号存在数组a中
for(i=1;i<=l2;i++)
b[i]=fuck(s2[i]);//将s2中的字符转化为序号存在数组b中
for(i=1;i<=l1;i++)//将f数组赋初值
f[i][0]=f[i-1][0]+p[a[i]][5];
for(i=1;i<=l2;i++)//同上
f[0][i]=f[0][i-1]+p[b[i]][5];
for(i=1;i<=l1;i++)//DP方程(上面有讲)
for(j=1;j<=l2;j++)
{
f[i][j]=max(f[i][j],f[i][j-1]+p[b[j]][5]);
f[i][j]=max(f[i][j],f[i-1][j]+p[a[i]][5]);
f[i][j]=max(f[i][j],f[i-1][j-1]+p[a[i]][b[j]]);
}
printf("%d\n",f[l1][l2]);//输出
return 0;
}
上一篇: P1140 相似基因 动态规划
下一篇: Java实现简单的Json解析器<二>