洛谷多校Round5 Gene
根据生物竞赛改的一道题目
题意大概是
给定两个碱基序列,
要把他们补起来,用gap,也就是空位,
补一个空位要用gamma的代价
如果两个位置相等有alpha的收益
否则付出beta的代价
补到长度相等
任意位置都能补
很明显是线性DP
N2的复杂度
对于没学过DP的我,先从搜索推起来就好了
这一位可能是加上了若干个gamma得到的
如果加上0个gamma 那么这一位都是核糖核酸了,那么就看一下 相同就alpha否则就beta
如果有一侧有gamma
那么就是从前一个退出来的
如果有两个有gamma
可以从一个的那种情况推过来
地推顺序:
先初始化一下,一侧被考虑到任意位,另外一侧没有考虑的情况,这样子只能补length个gap
然后把第一个串称为主串,第二个成为副串
从副串开始,在
注意字符串从第几位开始
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<limits.h> using namespace std; const int maxn = 5e3 + 3; typedef long long ll; ll dp[maxn][maxn]; ll alpha, beta, gamma; ll n, m; string s1, s2; int main() { cin >> n >> m >> alpha >> beta >> gamma; cin >> s1; cin >> s2; ll lim = max(n, m); for (ll i = 1; i <= lim; i++) dp[i][0] = dp[0][i] = -i * gamma; for(int i=1;i<=n;i++) for (int j = 1; j <= m; j++) { dp[i][j] = max(max(dp[i - 1][j], dp[i][j - 1]) - gamma, dp[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? alpha : -beta)); } cout << dp[n][m] << endl; return 0; }