涉及的算法:动态规划
题意:根据给定的字符间的相似度矩阵求出两个字符串的最大相似度
分析:对于两个给定的字符串X=(x1,x2,x3,......,xm),Y=(y1,y2,y3,......,xn);有三种可能的结尾方式:
第一种以xm、ym结尾,第二种以xm、- 结尾第三种以-、yn结尾
我们可以设dp[i][j]表示(x1,x2,....xi)与(y1,y2,......yj)的最大相似度,则有
dp[i][j]=max{dp[i-1][j-1]+s('xi,'yj'),dp[i-1][j]+s('xi','-'),dp[i][j-1]+s('-','yj')},其中s(‘a’,‘b’)表示字符a和b的相似度
import java.util.Scanner; public class Main_1080 { static char[] a; static char[] b; static int n,m; static int[][] dp; public static void main(String[] args) { Scanner in=new Scanner(System.in); int k=in.nextInt(); while(k-->0){ n=in.nextInt(); String s1=in.next(); m=in.nextInt(); String s2=in.next(); a=s1.toCharArray(); b=s2.toCharArray(); dp=new int[n+1][m+1]; dp(); } } //dp[i][j]表示a[0]~a[i-1]和b[0]~b[j-1]所能得到的最大分数 static void dp(){ dp[0][0]=0; for(int i=1;i<=n;i++){ dp[i][0]=dp[i-1][0]+s(a[i-1], '-'); } for(int j=1;j<=m;j++){ dp[0][j]=dp[0][j-1]+s('-', b[j-1]); } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ dp[i][j]=Math.max(dp[i][j-1]+s('-', b[j-1]), dp[i-1][j]+s(a[i-1], '-')); dp[i][j]=Math.max(dp[i][j], dp[i-1][j-1]+s(a[i-1], b[j-1])); } } System.out.println(dp[n][m]); } static int[][] s = {{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}}; static int s(char a,char b){ int x=0,y=0; if(a=='A') x=0; else if(a=='C') x=1; else if(a=='G') x=2; else if(a=='T') x=3; else if(a=='-') x=4; if(b=='A') y=0; else if(b=='C') y=1; else if(b=='G') y=2; else if(b=='T') y=3; else if(b=='-') y=4; return s[x][y]; } }