タイトル説明
最近、より多くの人々が株式市場、フーも少し心に参加します。覚えておいてください「株式市場のリスクは、投資家は慎重でなければならない、」福は株式取引の問題を単純化したバージョンで探すことにしました。
フーは、正確に次のN日に株式の価格を予測し、彼が得た最大の利益を作り、2の販売を期待していると仮定されてきました。シンプルさを計算するには、利益は販売価格マイナスの購入価格として計算されます。
同じ日に複数回取引することができます。彼らは二度目を購入することができます前に、しかし、最初の購入後、最初に販売しなければなりません。
さて、フーは、彼がまで取得することができますどのくらいの利益を知りたいと思いました。
入力形式
入力の最初の行は整数T(T≤50)であり、Tは、データの全体集合を表します。
次に、データの各グループ、最初の行は、整数N(1≤N≤100,000)で、Nは合計日表します。2行目は、毎日の株価を示し、スペースの整数で区切ってNです。日々の株価の絶対値が1,000,000を超えることはありません。
出力フォーマット
各データ出力ラインのため。ラインは福を得ることができる最大の利益を表す整数を含んでいます。
サンプル入力
3
7
5 14 -2 4 9 1 3
7
6 6 8 7 1 4 -2
4
18 9 5 2
サンプル出力
28
2
0
問題の解決策
私たちは、[i]は$ iが第二の取引日の$ n $の最初の日を$ $を表し[i]は$ iが最大の株式は、$ DP2を取引の最初の日を$最初の$に$ 1 $日を表し$のDP1を使用することができます倍の最大の株式。
易得$ ANS = \ {iがleqslantを\ n 1 \ leqslant} {最大} \左\ {DP1 [I] + DP2 [I] \右\} $ underset。
#include <iostreamの> する#include <cstdioを> の#define MAX_N(100000 + 5)を使用して名前空間STDを、int型T; int型のn; INT [MAX_N]。 int型のDP1 [MAX_N]、DP2 [MAX_N]。 int型ANS; INT メイン() { scanf関数(" %のD "、&T)。 int型のミナ、MAXA。 一方、(T-- ) { scanf関数(" %のD "、&N) 以下のために(登録int型 I = 1を ; I <= N。++ I) { scanf関数(" %のD "、A + I)。 } DP1 [ 0 ] = DP2 [N + 1 ] = ANS = - 0x7f7f7f7f 。 ミナ = 0x7f7f7f7f 。 MAXA = - 0x7f7f7f7f 。 用(登録をint i = 1 ; iが<= N ++ I) { ミナ = 分(ミナ、[I])。 DP1 [I] = MAX(DP1 [I - 1 ]、[I] - ミナ)。 } ため(登録int型 ; I; I = N - I) { MAXA = ([I]、MAXA)MAX。 DP2 [I] = MAX(DP2 [I + 1 ]、MAXA - [I])。 } ため(登録をint i = 1 ; iが<= N; ++ I) { ANS = MAX(ANS、DP1 [I] + DP2 [I])。 } COUT << ANS << " の\ n " 。 } 戻り 0 。 }