应该算是比较基础的一个DP,看到 n, m 的范围都在能开的下数组的范围内,果断开一个 f[i][j] 的数组表示一个串考虑到 i 位,另一个串考虑到 j 位,但是发现空格没有办法处理,如果加上末尾连续空格的长度则又要加上一维,时间复杂度有点。。。
所以应该将空格的长度转化为贡献,即如果前边有一个空格,那么空格的贡献是 -B 否则为 -A ,所以将定义改为 f[i][j][0/1][0/1] ,后边两维表示放没放空格,转移的时候考虑放字符还是放空格然后分别转移即可,写方程的时候才发现这个定义其实有些冗余,因为两个串的某个位置不可能都同时放空格,但是对时间复杂度影响不大,所以就没改。
#include <bits/stdc++.h>
#define N 3010
using namespace std;
int d[5][5], dp[N][N][2][2];
char s1[N], s2[N];
int a[N], b[N];
int main() {
memset(dp, -0x3f, sizeof(dp));
scanf("%s%s", s1 + 1, s2 + 1);
int n = strlen(s1 + 1), m = strlen(s2 + 1);
for(int i = 1; i <= n; i ++) {
if(s1[i] == 'A') a[i] = 1;
else if(s1[i] == 'T') a[i] = 2;
else if(s1[i] == 'G') a[i] = 3;
else if(s1[i] == 'C') a