POJ 1080 (DP)
题目:http://poj.org/problem?id=1080
两个串,求最大匹配度,可以插入‘-’,比如: AGTGATG GTTAG
有2种匹配方案:
(1)AGTGAT-G
-GT--TAG
(2)AGTGATG
-GTTA-G
a,b串,d[i][j] 表示a[0]~a[i-1]和b[0]~b[j-1]的匹配度。
a[i]和b[j]有三种匹配方案:
(1)a[i]~b[j];(2)a[i]~'-';(3)'-'~b[j]
于是有状态转移方程:
d[i][j] =max(
d[i-1][j-1]+f(a[i-1],b[j-1]),
d[i-1][j]+f(a[i-1],'-');
d[i][j-1]+f('-',b[j-1])
)
再注意下边界处理,就OK了。
代码:
#include <stdio.h> #include <string.h> char a[101],b[101]; int map[101][101]; int chart[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,10}}; int idx(char x); int max(int a,int b); int main() { int T,i,j,ans,alen,blen,tmp; scanf("%d",&T); do { scanf("%d%s",&alen,a); scanf("%d%s",&blen,b); memset(map,0,sizeof(map)); for(i = 1 ; i <= alen ; ++i) map[i][0] = map[i-1][0] + chart[idx(a[i-1])][idx('-')] ; for(i = 1 ; i <= blen ; ++i) map[0][i] = map[0][i-1] + chart[idx('-')][idx(b[i-1])]; for(i = 1 ; i <= alen ; ++i) for(j = 1 ; j <= blen ; ++j) { tmp = max(map[i-1][j-1]+chart[idx(a[i-1])][idx(b[j-1])], map[i-1][j]+chart[idx(a[i-1])][idx('-')]) ; map[i][j] =max(tmp,map[i][j-1]+chart[idx('-')][idx(b[j-1])]); } printf("%d\n",map[alen][blen]); }while(--T); system("pause"); return 0; } int idx(char x) { int ans; switch(x) { case 'A':ans = 0;break; case 'C':ans = 1;break; case 'G':ans = 2;break; case 'T':ans = 3;break; default: ans = 4;break; }; return ans; } int max(int a,int b) { return a>b? a:b; }