Human Gene Functions

ZOJ1027 Human Gene Functions

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=27

思路:算是最长公共子序列的拓展。。

设第一个字符串用char[] x存储
第二个字符串用char[] y存储
如果检索到 x 的第 i 个字符, y 的第 j 个字符,那么就只有三个选择方式。
1)x[i] 与 ‘-’配对
2)y[j] 与 ‘-’配对
3)x[i] 与 y[j] 配对
然后状态转移方程很容易推出来了。。
ps:提醒dp用边界预处理可以节省一定的时间

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class HumanGeneFunctions {
	static Map<Character, Integer> m = new HashMap();
	static Scanner sc = new Scanner(System.in);
	static int[][] gene = new int[5][5];
	static int[][] memo = new int[105][105];
	static int[][] dp = new int[150][150];
 	static int memoSearch(char[] x, char[] y, int xLast, int yLast) {
 		if(memo[xLast+1][yLast+1] != -5) return memo[xLast+1][yLast+1];
		if(xLast == -1 && yLast == -1) {
			memo[xLast+1][yLast+1] = 0;
		}
		else if(xLast == -1)
			memo[xLast+1][yLast+1] = memoSearch(x, y, xLast, yLast-1)+gene[4][m.get(y[yLast])];
		else if(yLast == -1)
			memo[xLast+1][yLast+1] = memoSearch(x, y, xLast-1, yLast)+gene[m.get(x[xLast])][4];
		else
			memo[xLast+1][yLast+1] = Math.max(Math.max(memoSearch(x, y, xLast-1, yLast-1)+gene[m.get(x[xLast])][m.get(y[yLast])]
				, memoSearch(x, y, xLast-1, yLast)+gene[m.get(x[xLast])][4]), 
				memoSearch(x, y, xLast, yLast-1)+gene[4][m.get(y[yLast])]);
		return memo[xLast+1][yLast+1];
	}
	static int recursion(char[] x, char[] y, int xLast, int yLast) {
		if(xLast == -1 && yLast == -1) {
			return 0;
		}
		if(xLast == -1)
			return recursion(x, y, xLast, yLast-1)+gene[4][m.get(y[yLast])];
		if(yLast == -1)
			return recursion(x, y, xLast-1, yLast)+gene[m.get(x[xLast])][4];
		return Math.max(Math.max(recursion(x, y, xLast-1, yLast-1)+gene[m.get(x[xLast])][m.get(y[yLast])]
				, recursion(x, y, xLast-1, yLast)+gene[m.get(x[xLast])][4]), 
				recursion(x, y, xLast, yLast-1)+gene[4][m.get(y[yLast])]);
	}
	static void dp(char[] x, char[] y, int len1, int len2) {
		for(int i = 1; i < len1; i++) {
			dp[i][0] = dp[i-1][0] + gene[m.get(x[i-1])][4];
		}
		for(int i = 1; i < len2; i++) {
			dp[0][i] = dp[0][i-1] + gene[4][m.get(y[i-1])];
		}
		for(int i = 1; i <= len1; i++) {
			for(int j = 1; j <= len2; j++) {
				dp[i][j] = Math.max(Math.max(dp[i-1][j-1] + gene[m.get(x[i-1])][m.get(y[j-1])]
						, dp[i-1][j] + gene[m.get(x[i-1])][4])
						, dp[i][j-1] + gene[4][m.get(y[j-1])]);
			}
		}
		System.out.println(dp[len1][len2]);
	}
	static void preprocess() {			//预处理基因数组
		m.put('A', 0);
		m.put('C', 1);
		m.put('G', 2);
		m.put('T', 3);
		m.put('-', 4);
		for(int i = 0; i < 4; i++) {
			gene[i][i] = 5;
		}
		gene[1][0] = gene[0][1] = -1;
		gene[2][0] = gene[0][2] = -2;
		gene[2][1] = gene[1][2] = -3;
		gene[3][0] = gene[0][3] = -1;
		gene[3][1] = gene[1][3] = -2;
		gene[3][2] = gene[2][3] = -2;
		gene[4][0] = gene[0][4] = -3;
		gene[4][1] = gene[1][4] = -4;
		gene[4][2] = gene[2][4] = -2;
		gene[4][3] = gene[3][4] = -1;
	}
	static void display(int len1, int len2) { //打印dp表,,可以任意改写,用于测试
		for(int i = 0; i < len1; i++) {
			for(int j = 0; j < len2; j++) {
				System.out.print(dp[i][j] + " ");
			}
			System.out.println();
		}
	}
	static void preprocess1(int len1, int len2) {		//初始化memo表
		for(int i = 0; i <= len1; i++) {
			for(int j = 0; j <= len2; j++) {
				memo[i][j] = -5;
			}
		}
	}
	static void preprocess2(int len1, int len2) {		//初始化dp表
		for(int i = 0; i <= len1; i++) {
			for(int j = 0; j <= len2; j++) {
				dp[i][j] = 0;
			}
		}
	}
	public static void main(String[] args) {
		preprocess();
		int t = sc.nextInt();
		sc.nextLine();
		while(t-->0) {
			int len1 = sc.nextInt();
			String str1 = sc.next();
			int len2 = sc.nextInt();
			String str2 = sc.next();
			preprocess2(len1, len2);
			dp(str1.toCharArray(), str2.toCharArray(), len1, len2);
			//display(len1, len2);
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值