2020ICPC·小米 网络选拔赛第二场 I Subsequence Pair(dp)

链接:https://ac.nowcoder.com/acm/contest/7502/I
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Bobo has two strings s and t. He would like to choose two subsequences x from s and y from t such that:

+ x is lexicographically smaller than or equal to y.
+ The sum of |x| and |y| is maximal, where |s| denotes the length of the string s.

Note that:

+ Both x and y could be empty string.
+ A subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements.
+ String x is lexicographically less than string y, if either x is a prefix of y (and x ≠ yx \ne yx ​= y), or there exists such i (1 ≤ i ≤ min⁡(∣x∣, ∣y∣)1 \le i \le \min(|x|, |y|)1 ≤ i ≤ min(∣x∣, ∣y∣)), that xi < yix_i < y_ixi​ < yi​, and for any j (1 ≤ j < i1 \le j < i1 ≤ j < i) xj = yjx_j = y_jxj​ = yj​.

输入描述:

The input consists of several test cases terminated by end-of-file. For each test case:

The first line contains a string s. The second line contains a string t.

* 1≤∣s∣≤20001 \le |s| \le 20001≤∣s∣≤2000
* 1≤∣t∣≤20001 \le |t| \le 20001≤∣t∣≤2000
* The sum of |s| does not exceed 20000.
* The sum of |t| does not exceed 20000.
* Both the strings consist only of English lowercase letters.

输出描述:

For each test case, output the sum of |x| and |y|.

示例1

输入

aaaa
bbbb
abcd
abca
abcd
abcd

输出

8
7
8

题意:分别从两个字符串s, t 中选取一个子序列 a, b,使得a < b(字典序),求a,b长度之和的最大值

思路:s 的长度为 ls,t ​​​​的长度为 lt,dp[i][j] 表示 s 的后缀 [i, ls - 1] 、t 的后缀 [j, lt - 1] 的最大值,从后向前遍历 i 和 j

(1)s[i] < t[j],表示后面的字符都可选,dp[i][j] = ls - i + lt - j

(2)s[i] == t[j],该位可以都选或选一个,都选是 dp[i + 1][j + 1] + 2,选一个的话是 dp[i][j + 1] 或 dp[i + 1][j],取最大值

(3)s[i] > t[j],该位肯定不能都选,可以选一个或都不选,选一个是 dp[i][j + 1] 或 dp[i + 1][j],都不选是dp[i + 1][j + 1],取最大值

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 2010;
int dp[maxn][maxn];
int main()
{
	string ss, tt;
	while(cin >> ss >> tt)
	{
		int ls = ss.size(), lt = tt.size();
		memset(dp, 0, sizeof(dp));
		for(int i = 0; i <= lt; ++i) dp[ls][i] = lt - i;
		for(int i = ls - 1; i >= 0; i--) {
			for(int j = lt - 1; j >= 0; j--) {
				if(ss[i] < tt[j])
					dp[i][j] = max(dp[i][j], ls-i + lt-j);
				else if(ss[i] == tt[j])
                    dp[i][j] = max({dp[i][j], dp[i + 1][j + 1] + 2, dp[i + 1][j], dp[i][j + 1]});
				else 
                    dp[i][j] = max({dp[i][j], dp[i + 1][j + 1], dp[i + 1][j], dp[i][j + 1]});
			}
		}
		cout << dp[0][0] << endl;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/109508163