NOI Online 2022 入门组 字符串 第三题题解

看着就很想用记忆化搜索是吧

\(dp_{i,j,k,l}\) 表示决策到 \(S\) 的第 \(i\) 位, \(R\) 中有 \(j\) 位无需删除,而且需要删除 \(R\) 的前 \(k\) 位和后 \(l\) 位。

那么我们分类讨论:
\(1. S_i = -\),那么 \(dp_{i,j,k,l}\) 可以转移到 \(dp_{i + 1,j,k,l - 1}\)\(dp_{i + 1,j,k - 1,l}\),也就是可以删除首位或者末位。

\(2.S_i≠ -\) 那么 \(dp_{i,j,k,l}\) 可以转移到 \(dp_{i + 1,j,k,l + 1}\),也就是说以后会被当做删除末位操作。

\(3. S_i ≠-\)\(j=0\)\(l=0\),那么 \(dp_{i,j,k,l}\) 可以转移到 \(dp_{i + 1,j,k + 1,l}\),也就是以后会被当做删除首位来操作。(\(j=0\)\(l=0\) 表示当前前面所有位置都被当做删除首位来处理)。

\(4. S_i ≠ -\)\(S_i = T_i\)\(l = 0\),那么 \(dp_{i,j,k,l}\) 可以转移到 \(dp_{i + 1,j + 1,k,l}\),也就是永远不删除该位。

但是这个四维显然 MLE 了(((

但是可以发现, \(j+k+l=i\) !

于是压缩掉一维,AC辣!!!

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int mod = 1e9 + 7;
const int N = 405;

int n, m;
string s, t;
ll dp[N][N][N];

ll slove (int i, int j, int k, int l) {
	if (i > n) {
		return j == m && !k && !l;
	}
	if (~dp[i][j][k]) {
		return dp[i][j][k];
	}
	ll res = 0;
	if (s[i - 1] == '-') {
		if (k) {
			res = (res + slove (i + 1, j, k - 1, l)) % mod;
		}
		if (l) {
			res = (res + slove (i + 1, j, k, l - 1)) % mod;
		}
	}
	else {
		res = slove (i + 1, j, k, l + 1) % mod;
		if (!j && !l) {
			res = (res + slove (i + 1, j, k + 1, l)) % mod;
		}
		if (s[i - 1] == t[j] && !l) {
			res = (res + slove (i + 1, j + 1, k, l)) % mod;
		}
	}
	return dp[i][j][k] = (res % mod);
}

int main () {
	int T;
	cin >> T;
	while (T --) {
		cin >> n >> m >> s >> t;
		memset (dp, -1, sizeof (dp));
		cout << slove (1, 0, 0, 0) % mod << endl;
	}
}
posted @ 2022-04-04 15:33  cyhyyds  阅读(158)  评论(0编辑  收藏  举报