標籤:class blog code 2014 string os
題意讀了半年,唉,給你兩串字元,然後長度不同,你可以用‘-’把它們補成相同長度,補在哪裡取決於得分,它會給你一個得分表,問你最大得分
跟LCS很像的DP數組 dp[i][j]表示第一個字串取第i個元素第二個字串取第三個元素,然後再預先處理一個得分表加上即可
得分表:
score['A']['A'] = score['C']['C'] = score['G']['G'] = score['T']['T'] = 5;score['A']['C'] = score['C']['A'] = -1;score['A']['G'] = score['G']['A'] = -2;score['A']['T'] = score['T']['A'] = -1;score['A']['-'] = score['-']['A'] = -3;score['C']['G'] = score['G']['C'] = -3;score['C']['T'] = score['T']['C'] = -2;score['C']['-'] = score['-']['C'] = -4;score['G']['T'] = score['T']['G'] = -2;score['G']['-'] = score['-']['G'] = -2;score['T']['-'] = score['-']['T'] = -1;score['-']['-'] = -inf;
那麼DP方程就好推了:
dp[i][j] = :
dp[i-1][j] + score[s1[i-1]][‘-‘]或者
dp[i][j-1] + score[‘-‘][s2[j-1]]或者
dp[i-1][j-1] + score[s1[i-1]][s2[j-1]]或者
這三者之中取最大的
然後就是邊界問題我給忘記了
不夠細心,若單單是i==0或者j==0,邊界問題就出現了,邊界不可能為0的,所以還得處理一下邊界
#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#include<cctype>#define ll long long#define LL __int64#define eps 1e-8#define inf 0xfffffff//const LL INF = 1LL<<61;using namespace std;//vector<pair<int,int> > G;//typedef pair<int,int > P;//vector<pair<int,int> > ::iterator iter;////map<ll,int >mp;//map<ll,int >::iterator p;const int N = 1000 + 5;int dp[N][N];int score[200][200];void init() {score['A']['A'] = score['C']['C'] = score['G']['G'] = score['T']['T'] = 5;score['A']['C'] = score['C']['A'] = -1;score['A']['G'] = score['G']['A'] = -2;score['A']['T'] = score['T']['A'] = -1;score['A']['-'] = score['-']['A'] = -3;score['C']['G'] = score['G']['C'] = -3;score['C']['T'] = score['T']['C'] = -2;score['C']['-'] = score['-']['C'] = -4;score['G']['T'] = score['T']['G'] = -2;score['G']['-'] = score['-']['G'] = -2;score['T']['-'] = score['-']['T'] = -1;score['-']['-'] = -inf;}int main () {init();int t;char s1[N];char s2[N];scanf("%d",&t);while(t--) {int n,m;memset(dp,0,sizeof(dp));scanf("%d %s",&n,s1);scanf("%d %s",&m,s2);for(int i=1;i<=n;i++)dp[i][0] = dp[i-1][0] + score[s1[i-1]]['-'];//邊界處理for(int j=1;j<=m;j++)dp[0][j] = dp[0][j-1] + score['-'][s2[j-1]];//邊界處理for(int i=1;i<=n;i++) {for(int j=1;j<=m;j++) {int t1 = dp[i-1][j] + score[s1[i-1]]['-'];int t2 = dp[i][j-1] + score['-'][s2[j-1]];int t3 = dp[i-1][j-1] + score[s1[i-1]][s2[j-1]];int maxn = max(t1,t2);dp[i][j] = max(maxn,t3);}}printf("%d\n",dp[n][m]);}return 0;}