私の最初の問題の解決

書き込みの説明に初めてライフ

より良い経験を読んで、クリックしてくださいここに

簡単な質問を分析した後、我々はこの問題は、サブ算術シリーズのオリジナルシリーズのどのくらいを依頼することですました。

データ範囲はそれを観察した後、本主題の最大高さの範囲が与えられます。データ範囲一定量を知るためにあるためにそう、我々は上記の二つに依存しようとするので、(時間またはスペース)における複合体の正溶液中で起こります。あまりないという問題がないので、私はこの問題を解決するための質問が唯一のいくつかのアイデアの内部で行われ、いくつかのテンプレートから学びたいと思っています。これは、問題のこのこんにゃく溶液中の最初の記事で、フロントの思考プロセスを説明し、前部は、より長いったらしいすることができ、あなたが戻っての部分を見ることができます$ AC $慣行で直接見てみたいことがあります。

ステータスの定義

私が定義されているDP文字の(例えばLCS $ $の長さなど)尺度は$ Fであるシーケンス(LCS $ $)内の要素の組成の選択の前またはI(LIS $ $)のシーケンスの最後に、我々は対象を考慮することができるので、それは[I] [J] F $の定義になるように[i]は$、もちろん、対象は、(例えば容量のバックパックとして)$制約付き$ jのが原因である可能性があり $の私たちが望む状態。この問題において、I第一の反射$ F [i]が$であるi番目の前に、それは$ I-1 <I $、を探すための列の要素選択された数は、算術で構成することができる $ F [i]が$ 組成一部は、サブシリーズ算術$ fの数である場合、[I-1] $ 、 i番目の要素は$私は$要素に投票してはならない前に、チャンスはi番目の要素とどのようにそれが結果であるが含まれている必要があり、ですそれは?これを計算するために、我々は寛容と多様なサブ算術$ fの最後の数の詳細を知るために、カラム内の[I-1] $、および組成物は$ $ [i]の等差数列に基づいているかどうか確認するために、私たちのしたいことDP矛盾の簡単な転送を見る前に、一時的にこのアイデアを放棄しました。

私たちが発見しただけの経験が$として[i]は$ F定義するかもしれないと、段落の終わりにI算術級数の数は、少なくとも我々は$ F知られ、等差数列の終わりを知っている、優れているJの$場合、あなたは$を見つけることができます[I] -a [J ] $、 列数Zeyangが、私たちはよりちょうどより少し進んときに、この時間は$急行許容範囲をその算術の$ F [j]を知りませんでしたが、ポイント。

我々は$公差[j]が第二の状態でF $の定義を知らない、我々はまた、他の何かが必要な場合があります。突然DP一般には多くのスペースであり、この状態は唯一の1000の配列、少し空のああを開く必要が定義されていると思いました!何か少ないですか?タイトルは、私が注意を払うが、この量は、初めですが、早期に思考を無視し、最大の数は20,000人以上ではない与え、言うために先頭を思い出してください。このようなもの、または複雑さ、スペースの複雑さは、いずれかの影響を与える時間に影響を与えます!私たちは許容範囲内で$ F [J] $を取り除くことができないことを考えると、それから、それは許容範囲ではない人為的にそれについて設定することができますか?$ F定義された制約の層を追加することを検討[I] [k]は$であるi番目の要素、及びサブ演算公差列番号kの数と終了我々は$ F [J] [k]がわかっている場合は、この時間は、 (J <I)$、 $ Fを求めているように、[I] [k]は $は、それが決定のみ$ [I] -a [Jさ ] とK $平等だけで罰金。これまでのところ、我々は、スペクトルの非常に心を持っています!

最初に考えたの伝達方程式

すべての既知のJ $ $ $ fの場合には、上記といえば[j]は[K]は(J <I)$、それは$ Fを見つけることができます[i]の[k]は$、おそらく見えましたこのように公差が$の要件を満たすと判断された場合の連続合計の$ F [i]が[K]として、式で表されます。

$ F [i]が[K] = \ sum_ {J} F [j] [k]は$、其中$ J <I $且$ [I] -a [J] = k個の$

この視点は、列挙$ iは、jは、k個の$は、タイムアウトは確かである(nは^ 2K)$をOの$複雑さがあるでしょう。しかし、それはあなたが再最適化を可能と思われ、すべての後に、これは正の解の最も可能性の高い思考は、私は考えることができるものです。満たすために、メモ$ [I] -a [J] == K $を合計することができ、その後、可能な最適化がある:我々は唯一の$ k個を列挙= [I] -a [J] $の状況、その許容値は、J $は$ iで完了しまし決定されます。そして、伝達方程式は次のような状況になりました。

$ F [i]は[I] -a [J] + = F [j]と[I] -a [J] $、其中$ J <I $

[I] -a [j]が、そう例えば20,000、数を追加するために、非負でないこと、例えば、入力データの最大の高さに注目

$ F [i]は[I] -a [J] +のmaxHeight] + = F [j]と[I] -a [J] +のmaxHeight] $、ここで、$、1 <= jの<私は$(最初の仮定添え字1)

これにより、問題を解決するためのコアが出て解釈されているように見えるです。(ただし、この式はまだ間違っています)

伝達方程式はもう一度考え、取引の詳細

DPは悪いコードを書くために、光伝達方程式があり、何度も理由の初期化及び境界治療の一つであり、他方は巡回順序です。ここでは、著者が限られている、多くの場合、開始、検索のメモリなので、唯一の問題との国境の契約について話をする、オーダーサイクルを議論する問題なく、この問題を回避する、読者にいくつかのインスピレーションを与えることを願っています。

今すぐ手に「伝達方程式」、のは、いくつかの暫定カウント数、見て右を見てみましょう。例えば、シーケンス1,2,3

手動初期化サブサブあると思われるもの$ F [1]は明らかである[0] = 1 $、

$ F [1] [1] = $?、これは少し混乱しているが、それはそれは、他の$ Fを先送り最初、0でなければなりません感じている[1] [] $ 0は、それを考えられています。

$ F [2] [0] = 1 $、または手動で初期化?それはちょっとビット面倒です。

$ F [2] [1] + = F [1] [1]?$ピタッああ!$ F [1] [1] = 0 $、と私たちの$ F [2] [1] $ 0が算出され、どうやらサンプルによると、1ああする必要があります!なぜ?私は思考、$ F [i]の[[i]は-a [J] +のmaxHeight]を除き、$を開始しているすべての$ F [j]は[[i]は-a [J] +のmaxHeight] $をしてますが事実ではありません。考慮すると、$ [i]は$および$ [I] -a [J 2つの演算、その分解を形成することができる$場合(すなわち内で$ [J] $トレランスケースの$ F [j]は[[i]は-a [J] +のmaxHeight] $は)のみ$ [j]が$であるべき、と明らかにのみ$ [j]は$ケース$に含まれていませんF [J] [[i]は-a [J] +のmaxHeight]で$。そこで、我々は、手動で1のみ$ [i]と等差数列の[J] $組成を補うためにしなければなりません。したがって、修飾された式であります:

$ F [i]は[I] -a [J] +のmaxHeight] + =(F [j] [i]は-a [J] +のmaxHeight] +1)$、ここで$、1 <= jの<私(添字1の最初の数を仮定して)$、+ 1は、$ [i]と[J]等差数列の$組成を補償します。

問題の二つの要素、間違っああではないであろう数との間の境界以来?我々はスタートのn周期(比較特定の)$ 2 $からすべての$ I $、$ 0 $の言葉に初期化され、ゆがん避けるために$ $ Fに始めている場合は、実際の数の算術シーケンスのすべての単一の要素の廃棄でありますしかし、のはなるシンプルを初期化してみましょう。補償として、列挙は、I $した後、$すべての$ F [i]が[K] k個 $ $ n要素(単一算術配列に合計、プラス$をも弾性率)、答えがあります。このように、我々は手動で境界問題を発見し、その後伝達方程式を改正し、初期化方法を決定シミュレートし、コードを書くには、特にそれを勇気づけています!

小最適化

全ての$ F [i]が[K] $をiは、kは$列挙 $ 合計は、$ O(NK)$複雑プログラムが存在するであろうことはショートボードです。私たちは、複雑$ O(N ^ 2)詳細は$は、すべての公差を横断する必要はありませんので、しかし、唯一の側のDPエッジオペレータの回答DP時に、それらの可能な公差の等差数列の組成物の場合を追加してください必要があるので、コードを見て。
コードは以下の通りであります:

#include <bits/stdc++.h>
#define ll long long
#define N 1009
#define V 20008
#define mod 998244353
using namespace std;
ll n,a[N],f[N][2*V],maxh=0,ans=0;
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        maxh=max(maxh,a[i]);
    }
    for(int i=2;i<=n;i++){
        for(int j=1;j<i;j++){
            f[i][a[i]-a[j]+maxh]=(f[i][a[i]-a[j]+maxh]+f[j][a[i]-a[j]+maxh]+1)%mod;
            //解释上式为何有+1:这个1指的是a[j]和a[i]这俩元素组成序列的情况,
            //在f[j][a[i]-a[j]]中仅有a[j]并不满足公差条件,所以要单独加上这个 
            ans=(ans+f[j][a[i]-a[j]+maxh]+1)%mod; 
            //我们不是用f[i][a[i]-a[j]+maxh]算的,而是直接加的f[j][a[i]-a[j]+maxh]+1
            //f数组仅用作dp,如果最后再算ans会慢 
        }
    }
    ans=(ans+n)%mod;
    printf("%lld\n",ans);
    return 0;
} 

おすすめ

転載: www.cnblogs.com/BUAA-Wander/p/12535968.html