poj 1080

来源:互联网 发布:杭州行知小学网址 编辑:程序博客网 时间:2024/06/05 17:28

       题意很好懂,不多说。

       此题是LCS问题的扩展,众所周知LCS求的是最长长度,而这里只是用一个搭配权值代替了长度而已,因此可以借用LCS的思想来求解。c[i][j]为两个字符串在分别在长度为i和j时所得的最长长度,由于可以首字母与‘-’相搭配,因此要有一个初始化过程(可见代码)。然后是状态转移,对于每个字符串的每个字符,其可以和‘-’搭配,也可以和另一个字符串的字符搭配,因此会有三种情况(之前合并成一种来考虑,结果做了很久都做不出。。。)。最后输出c[len1][len2]即可。

       以下是代码:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int M=200;const int inf=1<<29;int c[M][M];int a[M],b[M];int dir[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};char s[M],t[M];char dic[5]={'A','C','G','T','-'};int len1,len2;int getMark(char ch){for(int i=0;i<5;i++)if(dic[i]==ch) return i;}void LCS(){int i,j;for(i=0;i<=len1;i++){for(j=0;j<=len2;j++)c[i][j]=-inf;}c[0][0]=0;for(i=1;i<=len2;i++)c[0][i]=c[0][i-1]+dir[b[i]][4];for(i=1;i<=len1;i++)c[i][0]=c[i-1][0]+dir[a[i]][4];for(i=0;i<=len1;i++){for(j=0;j<=len2;j++){if(c[i][j]+dir[a[i+1]][4]>c[i+1][j])c[i+1][j]=c[i][j]+dir[a[i+1]][4];if(c[i][j]+dir[b[j+1]][4]>c[i][j+1])c[i][j+1]=c[i][j]+dir[b[j+1]][4];if(c[i][j]+dir[a[i+1]][b[j+1]]>c[i+1][j+1])c[i+1][j+1]=c[i][j]+dir[a[i+1]][b[j+1]];}}}int main(){int T;scanf("%d",&T);while(T--){int i;scanf("%d%s%d%s",&len1,s,&len2,t);for(i=0;i<len1;i++)a[i+1]=getMark(s[i]);for(i=0;i<len2;i++)b[i+1]=getMark(t[i]);LCS();printf("%d\n",c[len1][len2]);}return 0;}


 



原创粉丝点击