[タイトル]効果
$ $ N-タスクは特定の順序で処理しなければならない、I $ $ $ T_Iタスクは、$を完了するまでに時間がかかります。各バッチ処理タスクの開始前にマシンを起動するために、時間の$のS $を過ごすために、処理のためのいくつかのバッチに分割することができます。時間の初め$ 0 $から$私は有料の最初のタスクを完了するために$ $ C_I $乗その完了時間$(各タスクの完了時間$のためのタスク完了時間の数続く$タスク)であります$、最小限の総コストを見つけます。
[解析]アイデア
最初の単純な考えられる設け$ fは$ J $バッチの最小の総コストに$は$ I $タスク、転写式の$ F [I] [J] =分\ {Fの[前部を完了[I] [J]でありますK] [J-1] +(Sの* jを+ \ sum_ {X = 1} ^ {I} T_x)* \ sum_ {X = K + 1} ^ {I} C_x \}(0 \ルK <I) $
もちろん、時間計算量は$ O(N ^ 3)$で、これは我々が最適化する方法を検討し、オーバー確かではありません。
実際には、我々はマシンを再起動するたびに、時間の相当同時にプラス$ Sの$で後続のすべてのタスクを完了するために、それは我々が先にいくつかのグループに分割されているタスクを知っている必要はないと言うことです。
$(残りのタスクを含む$それは$のコストかかる余分の$ Sの$時間)$の$ I $タスク最小総コスト、$ fの伝達方程式前に完了提供の$ F [i]が$表す[I] = F分\ {[J] + \ sum_ {X = 1} ^ {I} T_x * \ sum_ {X = J + 1} ^ {I} C_x + S * \ sum_ {X = J + 1} ^ { n}はC_x \}(0 \ルJ <I)$
[]コードの実装
1の#include <cstdioを> 2の#include <iostreamの> 3の#include <CStringの> 4の#include <アルゴリズム> 5の#include <cmath> 6の#include <キュー> 7 の#define G()GETCHAR() 8 の#define RGレジスタ 9 の#defineは <;(= BをI ++は(I、B)iがRG iは= INT)に行く 10 の#defineバック(I、B)(RG iは= int型のために、I = B>。 i--) 11 の#defineダブルDB 12 の#defineは長い長いっ 13 の#define ILインライン 14 の#define PFのprintf 15 の#defineMEM(A、B)のmemset(A、B、はsizeof(A)) 16 使用 名前空間STDを、 17 LLのFR(){ 18 LL W = 0、Q = 1 。 19 CHAR CH = G(); 20 一方(CH < ' 0 ' || CH> ' 9 ' ){ 21 であれば(CH == ' - ')、Q = - 1 。 22 CH = G(); 23 } 24 ながら、(CH> = ' 0 ' && CH <= ' 9')(= W W << 1)+(W << 3)+ CH- ' 0 '、CH = G(); 25 リターン * wのQ; 26 } 27 のconst int型 N = 5002 。 28 INTのN、S。 29 LLのF [N]、ST [N]、皮下[N]。 30 INT メイン(){ 31 // freopenは( ""、 "R"、STDIN)。 32 // freopenは( ""、 "" W、STDOUT)。 33 N = frの(); S =のFR()。 34 ゴー(I、1、N)ST [I] = ST [I- 1 ] + FR()、SC [I] = SC [I- 1] + FR()。 35 MEM(F、0x3fを); [F 0 ] = 0 。 36 ゴー(I、1、n)の移動(j、0、I- 1 ) 37 F [I] =分([I]、F [j]がF + ST [I] *(SC [I] -sc [ J])+ S *(SC [N] - SC [J]))。 38 PF(" %LLDする\ n " 、F [N])。 39 リターン 0 ; 40 }