CF1272D。問題への一つの要素の動的プログラミングソリューションを削除します

トピックリンク:http://codeforces.com/contest/1272/problem/D

タイトル効果は:
あなたの長さを与えるために\(N- \)の配列は、最大で1つの要素を削除する(または削除することはできません)、部分文字列の長さの制限条件で最大の増加を見つけます。

問題解決のアイデア:
この質問は、アルゴリズムに関する:動的なプログラミングを。

まず、条件があります。「あなたは一つの要素の最大値を削除することができます」、この条件は回避トラブルにそうために、私たちに多くの問題を引き起こす可能性があり、我々は最初の条件は、非存在下での問題を解決しよう。

要素を削除するための許可なしに、アレイ当社で\(A \)\(N- \)要素が固定されているので、このケースでは、状態定義することができる(F [i]が\)\で表さを[(\ I ] \)端とを含む\([I] \)我々は(から提供された配列座標を見つけることができ、最長のサブストリングの長さを増加させるために\(\ 1)を開始します)。

\(F [1] = 1 \。) ;
もし(I \ GT 1 \)\時間、

  • 如果 \(a[i-1] < a[i]\) ,则 \(f[i] = f[i-1]+1\)
  • そうでない場合、\(F [I] = 1 \)

コードの実装:

f[1] = 1;
for (int i = 2; i <= n; i ++) {
    if (a[i-1] < a[i]) f[i] = f[i-1]+1;
    else f[i] = 1;
}

その後、我々は、サブストリングの必要な長さを長くする必要があるすべての最長です\(F [i]が\)最大1インチ
ちょっと待って、私たちがやるか、この状態の「あなたは一つの要素の最大値を削除することができ、」追加しないでください。
この条件を追加する前に、我々は状態を定義する(G [i]が\)は\で表される([I] \)\始まり含む\([I] \)最長文字列の長さの増加をそう、我々は状態遷移方程式を得ることができます。

\(G [N-] = 1 \。) ;
場合(I <N \)\時間、

  • もし(A [I] <A [I + 1] \)\、次に\(G [I] G = [I + 1] + +1 \)
  • そうでない場合、\(G [I] = 1 \)

(注コードの実装\(G [i]が\)から必要な(N- \)\\(1 \)前方トランスプッシュ):

g[n] = 1;
for (int i = n-1; i >= 1; i --) {
    if (a[i] < a[i+1]) g[i] = g[i+1]+1;
    else g[i] = 1;
}

その後、我々は、完成BEG \(F [i]が\)\(G [i]が\)それの後に、この条件の「あなたは一つの要素の最大値を削除することができます」のバック追加してみましょう。

我々は要素を削除しない場合、答えは全てれるまず、\(F [i]が\)が最大で、我々は変数開く\(ANS = \ MAX(F [i]のを)\)

我々は、要素座標を削除する第二に、\(I \) 我々は、要素に対応する最長のサブシーケンスの増加が削除されると仮定する([L] \)\\(A [R&LT] \)
次いで場合(\をI \)が満たされていない(L <I <R \ \ ) 条件、その後、私は削除しますか\([I] \)私の答えには影響を与えません(まだ\(ANS = \ MAX(F [I ]) \))。

だから、とき答えは、それに影響を与えるのだろうか?
その場合\(1 <I <N \ ) と\([I-1] <[I + 1] \) 、I削除([I] \)\可能\(F [1- 1] + G [I + 1 ]> ANS \) 要素を除去するための命令場合\([I] \)最長のサブの増大成長の効果には、我々は更新(ANS = F [1- \ 1] + G [I + 1] \)

要約すると、答えがでなければなりません

  • \(\ MAX(F [I])\) ここで、\((1 \ Iル\ N-LE)\)

  • \(\ MAX(F [I-1] + G [I + 1])\)(其中\(1 \ LT I \ LT N \)\([I-1] <[I + 1] \)

大きい方の値。

次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200020;
int n, a[maxn], f[maxn], g[maxn], ans;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    f[1] = 1;
    for (int i = 2; i <= n; i ++) {
        if (a[i-1] < a[i]) f[i] = f[i-1]+1;
        else f[i] = 1;
    }
    g[n] = 1;
    for (int i = n-1; i >= 1; i --) {
        if (a[i] < a[i+1]) g[i] = g[i+1]+1;
        else g[i] = 1;
    }
    for (int i = 1; i <= n; i ++) ans = max(ans, f[i]);
    for (int i = 2; i < n; i ++) if (a[i-1] < a[i+1]) ans = max(ans, f[i-1] + g[i+1]);
    cout << ans << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/quanjun/p/12041388.html