HDU1024最大合計プラスプラス[DP]

最大合計プラスプラス

制限時間:1000分の2000 MS(Javaの/その他)メモリの制限:32768分の65536 K(Javaの/その他)
の合計提出(S):42745受理提出(S):15453


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

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

今、整数m(メートル> 0)が与えられ、あなたのタスクは、合計(I作るメートルiのペアとj見つけることです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は怠惰な、私はあなたが出力M iのペアとjに持っていないので、特別なジャッジモジュールを書きたくない、和のちょうど出力最大合計は、(iはxは jは、X 1() ≤Xさ≤m)の代わり。^ _ ^
 

 

入力
各テストケースは、nは整数Sに続く二つの整数mおよびnは、で始まります1、S 2、S 3 ... SのN
ファイルの終わりまでのプロセス。
 

 

出力
出力最大合計は、1行に上記の。
 

 

サンプル入力
1 3 1 2 3 2 6 -1 4 -2 3 -2 3
 

 

サンプル出力
6 8
ヒント
巨大入力、scanf関数と動的プログラミングが推奨されます。

 

解像度:

質問の意味:

連続するm個のサブセクション、サブセグメントの分割数nおよびSO最大ことが重なりません。


 

DP [i] [j]は選択番号、及びグループIの最大数を割るJを示しています。

その後、任意のjに対して、我々は2つの決定を持っています:

  1. 以前に分割して組み合わせると、それ。
  2. 新しいセットとして、独自の独立。

私たちは、状態遷移方程式を書くことができます。

DP [I] [J] = MAX(DP [I]、[J-1] + [J]、DP [I-1] [K] + [J])、其中I-1 <K <= N

第1の決定DP [I]、[J-1] + [j]を決定2に対応する決定、第2の決定DP [I-1] [K] + [J]に相当します。

なぜI-1 <K <= nのそれkの値はありますか?

まず、我々は明確にする必要があり、この時間kと、その後は、I-1または前の値を取る場合、i番目のグループの一部門で、iは、1グループに少なくともI-1番号の前に、それは確かに真実ではないとき、結局のところ、あなたは内数5 10非重複範囲の外に引き出すことができません。

しかし、そうすることだけではなく、MLEは、TLEますされます。

 

私たちは、最適化を検討する必要があります。

我々は現在の状態のDP配列に気づき、たったの約状態の前に、前にすべてのステータスの更新を検討することなく、私たちは、スクロールを追加しましたので、最初は、回転式配列です。

しかし、それだけではないスペースを最適化します。

 

その後、我々は、このKを扱う考慮する必要があります。

我々は明確な意味のKでなければなりません:グループを分割するとき、私は、我々は最適な状態転送を見つけるためにI-1のグループの状態を分割する必要があります。私たちはあなたの代わりにI-1この段階でそれを再度スキャンするので、最適な状態kを選択するときの間で選択することができ、次のステージのために最適な状態の現在の段階ですべての良いレコード内のプロセスを転送するかもしれないという。

だから我々は、事前に、アレイに従事検討することができグループがそれを記録したときに[i]はi番目のは、最適なソリューションを分けます。

アレイは、予め[j]を許可している場合しかし、それはプレ配列を再利用できるため、前段選択j番目の数は、より最適化することができる場合、最適なソリューションを表し、DPは、さらに一次元に圧縮することができます。

だから我々はあなたが事前に[J-1]について、更新したとき、jの番号を選択し、最大まで保存するたびがj-1が含まれていません。各状態の後に現在の最大転送と事前配列を更新することに注意してください!

最後に、状態遷移方程式を得ます:

DP [J] = MAX(DP [J-1] + [J]、プリ[J-1] + [J])。

参照コード:

1の#include <cstdioを>
 2の#include <iostreamの>
 3の#include <cmath>
 4の#include <CStringの>
 5の#include <ctimeの>
 6の#include <cstdlib>
 7の#include <アルゴリズム>
 8の#include <キュー>
 9#含む< 設定 >
 10の#include <地図>
 11  の#define INF 0x3f3f3f3f
 12  のconst  int型 N = 1000010 13  使用して 名前空間STDを、
14  INT [N]、DP [N]、[N]を事前。
  {
 17      int型N、M。
18      一方(scanf関数(" %D%dの"、&​​M、&N)=!EOF)
 19      {
 20          のためのint型 i = 1 ; iが<= N; iが++)のscanf(" %dの"、および[I])。
21          のmemset(DP、0はsizeof (DP))。
22          のmemset(前、0はsizeof (PRE))。
23          DP [ 0 ] = - INF。
24の         int型のANS;
25          のためにint型 I = 1 ; I <= M; iは++ ){
 26の              ANS = - INF。
27              のためのint型 J = I; J <= nであり、j ++ ){
 28                   、DP [J] = maxが(DPは[J- 1 ] + [J]、あらかじめ[J- 1 ] + [J])。
29                   プレ[J- 1 ] = ANS。
30の                   ANS = MAX(ANS、DP [J])。
31               }
 32          }
 33          COUT << ANS << ENDL。
34      }
 35      リターン 0 36 }

 

おすすめ

転載: www.cnblogs.com/DarkValkyrie/p/11105771.html