2020ICPC・XiaomiインターネットトライアルトーナメントIサブシーケンスペア(dp)

リンク:https
://ac.nowcoder.com/acm/contest/7502/I出典:Niuke
 

制限時間:C / C ++ 1秒、他の言語2秒
スペース制限:C / C ++ 262144K、他の言語524288K
64ビットIO形式:%lld

タイトル説明

ボボには2つの文字列sとtがあります。彼は、次のように、sからxとtからyの2つのサブシーケンスを選択したいと考えています。

+ xは辞書式順序でy以下です。
+ | x |の合計 および| y | は最大です。ここで| s | 文字列sの長さを示します。

次の点に注意してください。

+ xとyの両方が空の文字列である可能性があります。
+サブシーケンスは、残りの要素の順序を変更せずに0個以上の要素を削除することにより、指定されたシーケンスから派生できるシーケンスです。
+文字列xは、xがyの接頭辞(およびx≠yx \neyx= y)であるか、そのようなi(1≤i≤min⁡(∣x∣、∣)が存在する場合、辞書式順序で文字列yよりも小さくなります。 y∣)1 \ le i \ le \ min(| x |、| y |)1≤i≤min(∣x∣、∣y∣))、そのxi <yix_i <y_ixi <yi、および任意の場合j(1≤j<i1 \ le j <i1≤j<i)xj = yjx_j = y_jxj = yj。

説明を入力してください:

入力は、ファイルの終わりで終了するいくつかのテストケースで構成されます。テストケースごとに:

最初の行には文字列sが含まれています。2行目には文字列tが含まれています。

* 1≤∣s∣≤20001 \ le | s | \ le20001≤∣s∣≤2000 
* 1≤∣t∣≤20001 \ le | t | \ le20001≤∣t∣≤2000 
* | s |の合計 20000を超えない。
* | t |の合計 20000を超えない。
*両方の文字列は英語の小文字のみで構成されます。

出力の説明:

テストケースごとに、| x |の合計を出力します。および| y |。

例1

入る

aaaa 
bbbb 
dac 
abca 
dac 
dac

出力

8 
7 
8

タイトルの意味:a <b(辞書式順序)となるように、2つの文字列s、tからそれぞれサブシーケンス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]このビットはまったく選択できません。1つまたはなしを選択するdp [i] [j + 1] かdp [i + 1] [j]1を選択するか なしを選択して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