题意:给出一个表,碱基ATCG按照这个表配对,可以自己加空格,求最终配出来的最大值。
解:古老的记忆苏醒了。。。想起以前菲菲把G改成一只鸟然后说这是鸟嘌呤,好可爱来着。
咳,类似两个字符串配对。先看LCS的转移方程:a[i]=b[j]的时候dp[i][j]=dp[i-1][j-1]+1,不等的时候从dp[i-1][j]和dp[i][j-1]里挑一个。
到这道题就是dp[i][j]=dp[i][j-1]时,相当于b[j]和空格配对,再加上相应的值。另一个同理。转移方程很好写。
然后忘了多组输入输出清空数组WA了好几次。。。
代码:
#include<stdio.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <queue> #include <stdlib.h> #include <string> #include <cstring> using namespace std; #define ll long long #define maxx 205 #define eps 0.00000001 #define inf 0x7fffffff //#define int long long char a[maxx],b[maxx]; int n,m; int dp[205][205]={0}; int dis[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,-100}; int val(char c){ if(c=='A') return 0; if(c=='C') return 1; if(c=='G') return 2; if(c=='T') return 3; if(c==' ') return 4; } signed main() { int T; scanf("%d",&T); while(T--){ scanf("%d",&n); scanf("%s",a+1); scanf("%d",&m); scanf("%s",b+1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dp[i][j]=-inf; for(int i=1;i<=m;i++) dp[0][i]=dp[0][i-1]+dis[val(b[i])][val(' ')]; for(int i=1;i<=n;i++) dp[i][0]=dp[i-1][0]+dis[val(a[i])][val(' ')]; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ dp[i][j]=max(dp[i][j],dp[i-1][j-1]+dis[val(a[i])][val(b[j])]); dp[i][j]=max(dp[i][j],dp[i-1][j]+dis[val(a[i])][val(' ')]); dp[i][j]=max(dp[i][j],dp[i][j-1]+dis[val(' ')][val(b[j])]); } } printf("%d\n",dp[n][m]); } return 0; }