Day9 - E - 最大合計プラスプラスHDU - 1024

今、私はあなたがIgnatius.Lの「マックス・サム」問題での交流を持っていると思います。勇敢ACMerであるために、私たちは常により多くの困難な問題に自分自身に挑戦します。今、あなたは、より困難な問題に直面しています。

所定の連続数配列は、S  1 、S  2 、S  3 、S  4  ... S  X 、... S  N  (1≤X≤N≤1,000,000、-32768≤S  X  ≤32767)。私たちは、(i、j)は関数の和を定義= S  I  + ... + S  J  (1≤I≤J≤n)を。

今、整数m(m> 0)で与えられ、あなたのタスクは、iとjメイク和のm個のペアを見つけることです(I  1 、J  1 )+ SUM(I  2 、J  2 )+ SUM(I  3 、J  3 )+ ... + SUM(I  M 、jは  M )最大(I  X  ≤I  Y  ≤J  X  またはI  xは  ≤j個の  Y  ≤jは  X  許可されていないが)。

しかし、I`m怠惰が、私はあなたがiとjの出力m個のペア、ちょうど出力に和の最大の合計を持っていないので、特別なジャッジモジュールを記述する必要はありません(私は  xは 、j個の  Xを )(1 ≤X≤m)の代わり。^ _ ^

InputEachテストケースは、M個の二つの整数で始まりそしてn、nは整数Sに続くであろう  1、S  2、S  3  ... S  N
ファイルの最後に処理します。
OutputOutput最大の合計は、1行に上記の。
サンプル入力

1 3 1 2 3
2 6 -1 4 -2 3 -2 3

サンプル出力

6
8


        
 

ヒント

巨大入力、scanf関数と動的プログラミングがされている 。推奨

アイデア:Mの最大片部との問題、提供和[n]は[m]はフロントN、M及び最大セグメントピースの数であり、そこ3つの状態遷移は、
1.A [N- ] M] [] 1。m番目のセグメントと最大、合計[n]は[M] =合計[N-に属さない
] N-] [2.A最大に属し、和の新しい期間[N m番目の段落の[M] = SUM [N - 1] [1-M] + [N-] A
3.A最初の段落と最大に属する[N- Mは、新しい段落和[n]は[M] =ではない和[ N-1] [M] + [N]は
、状態遷移方程式、矛盾および3を知ることは容易であり、B [n]は[M]を含むように、補助第2の状態遷移方程式を見つけることが必要です[最大セグメントN M前のサブセグメントの数n]と、知られていることにより、セグメントmおよびnは、[N]は必ずしも含まれていない前に、SUM [n]は[m]は、サブセグメントの最大数である場合、和[n]は[M] = MAX(B [j]は[M])(M <= J <= N)、 最終的な答えは、合計である[N] [M]
上記の分析から、B [n]を描画することができる[m]は、Mの部分である状態遷移方程式である[N] / m番目の段落、すなわち、B [n]は[M] = MAX(B [N-1、属しません] [M]、合計[N-1] [M-1])+ [n]は、式により逐次計算することができ、Bを算出[n]は[M]、必要和[N-1] [M-1]、B [N-1] [M]、及びその後和[n]は[M])を更新し、和の計算に[n]は[M] = MAX(B [j]は[M])(nは<= J <= M)、アナログ和[n]は[m]を計算する際に、完全にバックパック最適化された、合計[n]は[M] = MAX(B [j]は[M])(M <= J <= N)=最大[N](B [M]、合計[N-1] [M])、和は[N-1] [M] = MAX(B [X] [M])(M <= X繰り返す必要はありません、一度<= N-1)、式和[n]は[m]を算出した和[N-1] [M]が計算される前に、我々は、小から大への順序を列挙し、保持しています列挙
const  int型 MAXM = 1005 ;

INT 和[MAXM] [MAXM]、B [MAXM] [MAXM]、[MAXM]。

INT メイン(){
    イオス:: sync_with_stdio()、cin.tie(0 );
    整数N、M。
    int型TMP;
    一方、(CIN >> M >> N){
        memset(和、0はsizeof(合計))、memsetの(0はsizeof())、memsetの(B、0はsizeof (b)参照)。
        以下のためにINT iが= 1 ; I <= N; ++ I)CIN >> [I]。
        以下のためにINT iは= 1 ; I <= M; ++ I){
             ためINT J = I; J <= N; ++ j)は{
                B [j] [i]は = MAX(B [J- 1 ] [i]は、和[J- 1 ] [I- 1 ])+ [J]。
                和[J] [I] = MAX(和[J- 1 ] [I]、B [j]は[I])。
            }
        }
        COUT <<和[n]は[M] << ENDL。
    }
    リターン 0 ;
}
問題の範囲は1E6であると、二次元空間が明確に揚げているノートは、しかし、一次元アレイの回転を最適化する必要がある、我々は、式を計算するに列挙する:
B [N-] [M] = MAX(B [ N-1] [M]、合計[N-1] [M-1])+ [N]、合計[n]は[M] = MAX(和[N-1] [M]、B [n]は[M])
小から大までスクロールしながら、J前の位置、jは[] [M]、jは後に[] [M-1](最後の)、[Bを計算する]であります和を更新する前に、[]、及び和Bの競合、第1の和[N-1] [Mため -1]、 次いでその和[N-1] [M ]、TMPを記録するために使用されています
const  int型 MAXM = 1E6 + 5 

INT 和[MAXM]、B [MAXM]、[MAXM]。

INT メイン(){
    イオス:: sync_with_stdio()、cin.tie(0 );
    整数N、M。
    int型TMP;
    一方、(CIN >> M >> N){
        memset(和、0はsizeof(合計))、memsetの(0はsizeof())、memsetの(B、0はsizeof (b)参照)。
        以下のためにINT iが= 1 ; I <= N; ++ I)CIN >> [I]。
        以下のためにINT iは= 1 ; I <= M; ++ I){
            TMP = - 0x3f3f3f3f INT J = I; J <= N; ++ j)は{
                B [J] = MAX(B [J- 1 ]、SUM [J- 1 ])+ A [J]; // ここで、合計は[J-1]は、I-1番目のセグメント 
                SUM [J- 1 ] = TMP;   // i番目の段落の更新和[J-1]、段落がTMP I、J-1であり、サイクルタイム継承上の 
                TMP = MAX(SUM [J- 1 ]、B [J ]); // 更新TMP、TMPは、次のサイクルのJ段落I、J-1です
            }
            和[N] = TMP。
        }
        coutの <<合計[N] << " \ n個" ;
    }
    リターン 0 ;
}
 

 参考マイクロブログ:https://www.cnblogs.com/chuckcpc/p/dp_Max_M_Sum.html

 

おすすめ

転載: www.cnblogs.com/GRedComeT/p/12237217.html