タイトル説明
ジョンは彼がフィードのKトンと一緒に家に行くと、町に行きました。彼の車は、X ^ 2万ドルを費やす必要がありますキロあたりの飼料のXトンを持っていた場合は、フィードを輸送することは、コストがかかり、キロD D * X ^ 2万ドルを駆動する必要があります。ジョンNフィード店から購入することができ、店は、すべての座標軸であり、i番目の店舗の位置が西、トンあたりのCIの元、在庫Fiのための飼料の価格です。
ジョン= Oは軸の座標X = E.上で、X自宅の座標から正の方向に前進し始めました フィードKのホームトンをもたらすためには、ジョンの最小コストはどのくらいですか?
その店の在庫のすべてとK.下回らないと仮定すると、
例えば、として示す三店は、次のことを想定:
座標X = 1 X = 3 X = 4、E = 5
ストック111
価格122
、K = 2の場合、最良の選択は、家にあるジョン・お金近い2つのストアフィードを購入し、その後、道路に費やすお金がストア2 + 2 = 4、9元の合計で費やされ、1 + 4 = 5です。
考え
$ dpが[I] [J] $ 飼料1トンと$ $ I $ J $の最小コストを表しています。(この時間は、私が店を購入していないことに注意してください)
各店舗では、我々は、I-1 $、そして$のDP [I] [J] =分(DP [I-1] [k]の前にフィードを$ $ $ Kを列挙、購入する購入するかどうかを選択することができます+ J * jのの*(D [i]は-d [I-1])+(JK)* C [i])と$
整理一下:$ DP [I] [J] =分(DP [I-1] [K] -kの*のC [I] + J *はJ×(D [i]が-d [I-1])+ J * C [i])と$
単調キューがdp [I-1] [k]が最小のkを転送することを維持します。
コード
#include <ビット/ STDC ++ H>
使用して 名前空間STDを、
typedefの長い 長いLL。
const int型 K = 10010 ;
CONSTの INT N = 510 。
LLをF [N] [K]。
int型K、HM、N。
構造体FARM
{
LLのX、V、W。
} [N]。
LLのD [N]。
ブールCMP(ファームA、農場B)
{
戻り AX < BX。
}
int型のmain()
{
scanf関数(" %D%D%D "、&K、&HM、&N)
以下のための(int型i = 1 ; iは= <N; iは++)のscanf(" %LLD%LLD%LLD "、および[I] .X、&[I] .V、&[I] .W)。
ソート( + 1、A + 1 + N、CMP)。
N ++; [N] =(FARM){HM、0、0 }。
以下のために(int型 i = 1 ; iは= N <; iは++ )
D [i]は = [I] .xa [I- 1 ] .X。
memsetの(F、0x3fを、はsizeof (F))。
F [ 0 ] [ 0 ] = 0 。
以下のための(int型私は=1 ; iは++; iが= N < )
{
両端キュー < INT > Q。
用(INT J = 0 ; J <= K; J ++ )
{
ながら(!q.empty()&& J-q.front()> [I- 1 ] .V)q.pop_front();
一方!(q.empty()&& F [I- 1 ] [q.back()] - [I- 1 ] .W * q.back()> = F [I- 1 ] [J] -a [ I- 1 ] .Wの*のJ)
q.pop_back();
q.push_back(J)。
INT P = q.front()。
もし(!q.empty())[I] [J] = F F [I- 1] [P] -a [I- 1 ] .W * P + [I- 1 ] .Wの* jを+ jは*のj個の*のD [i]は、
}
}
COUT << F [N] [K]。
}