POJ 1080 Human Gene Functions(动态规划——LCS问题变形)

//DP动态规划,LCS问题变形。根据LCS经典模型,我们就用dp[I,j]表示匹配到i和j的最优值.最终答案就是DP[LEN1][LEN2] //显然有两种情况: //一、s1[i] == s2[j],也就是遇到相同字母的,状态转移自然是dp[i][j] = 5 + dp[i-1][j-1] //二、s1[i] != s2[j],遇到不同的呢,有这么几种匹配情况: // 1、硬将s1[i]和s2[j]匹配上去 // 2、不匹配,拿他们去和空格匹配,这样就有2种匹配方案 // dp[i][j] = max(match + dp[i-1][j],match + dp[i][j-1]),要么s1[i]去和空格匹配,要么s2[j]去和空格匹配 //对第二种情况画个图就清晰了 //....A ....A ...A_ //....C ...C_ ....C //最后就是边界以及初始化问题了~要求的是最大优值,那么初始化dp就是-INF //在初始化dp[0][i]和dp[i][0]的边界就可以了,就是拿他们全部和空格去匹配这种边界 #include<iostream> #include<cstring> #define INF 1000000000 using namespace std; int match[128][128],T; int dp[105][105]; char s1[105],s2[105]; int len1,len2; void init()//匹配分值的数组 { match['A']['C'] = match['C']['A'] = -1; match['A']['T'] = match['T']['A'] = -1; match['A']['G'] = match['G']['A'] = -2; match['C']['T'] = match['T']['C'] = -2; match['C']['G'] = match['G']['C'] = -3; match['T']['G'] = match['G']['T'] = -2; match['A'][' '] = match[' ']['A'] = -3; match['C'][' '] = match[' ']['C'] = -4; match['T'][' '] = match[' ']['T'] = -1; match['G'][' '] = match[' ']['G'] = -2; } int main() { init(); //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%s",&len1,s1+1); scanf("%d%s",&len2,s2+1); for(int i = 0;i <= len1;++i) for(int j = 0;j <= len2;++j) dp[i][j] = -INF; dp[0][0] = 0; for(int i = 1;i <= len2;++i) dp[0][i] = match[s2[i]][' '] + dp[0][i-1]; for(int i = 1;i <= len1;++i) dp[i][0] = match[s1[i]][' '] + dp[i-1][0]; //上面几行都是初始化边界 for(int i = 1;i <= len1;++i)//DP过程 { for(int j = 1;j <= len2;++j) { if(s1[i] != s2[j]) { dp[i][j] = max(dp[i][j],dp[i-1][j-1]+match[s1[i]][s2[j]]); dp[i][j] = max(dp[i][j],max(dp[i-1][j]+match[s1[i]][' '],dp[i][j-1]+match[s2[j]][' '])); } else dp[i][j] = max(dp[i][j],5 + dp[i-1][j-1]); } } printf("%d/n",dp[len1][len2]); } } 

你可能感兴趣的:(POJ 1080 Human Gene Functions(动态规划——LCS问题变形))