今、私はあなたが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)の代わり。^ _ ^
所定の連続数配列は、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