B - ローレンス
ここでは、私は、この式で書いていないハード、ハードDPを見つけます。
問題へのオンラインソリューションを読んで、私はこの移行式DPを理解するのに長い時間を読んで
DP [I] [j]は、1〜jをjのビットを示し、Iセクションに最小重量で終わると
次いで、Wは[B] Bの重量と、これは接頭辞ではないことに注意が、被写体の種類や重量のある配列を定義
こうした4 5 1 2つの戦略的価値は4 * 5 + 4 * 1 + 4 * 2 + 5 * 1 + 5 * 2 + 1 * 2 = 49であるbにあります。
49 = [a、b]はW
次いで、wは== [I]ヴァルを定義する[1、i]は[I]接頭重みとval [I] = valの[I-1] +和[I-1] *ことを意味
このWは[a、b]はない直接導入することが、接頭辞によって押し出すことができるからです。
求W [A + 1、B] = valの[B] -Val [A] - (和[B] -sum [A])*和[A]
そして、式DPは、それを起動することができます
DP [I、J] =分(DP [I-1、K] + W [K + 1、j])
直接的な暴力のn ^ 3を超える間違いではありません。しかし、それは、最適化する必要があり、この式はのような最適化式の傾きの前に押し通されていません。
DPなら[I-1、k]はk個の付加価値もあり、一般的に傾きDPの最適化によって最適化することができます。
そして、それは(を参照する前に、式の前にとして導入することができるD -真珠HDU - 1300二部斜面DP + スロープA DP - 3507 -印刷資料では、この記事では、HDUました)
令F [H]はDP [I-1]〜[H] -Val [H] +和[H] *和[時間] =
所以G [H、K] =(F [H] -F [K)/(和[H] -sum [K])<和[J]
そして、同じことが推定されます
私がある場合> J> K G [I、J]> G [J、K]
1 G [I、J]> Gjを、K]> [T]和より優れたK jは、jの好ましい比I
2 G [I、J]>和[T]> G [J、K] J好ましくはI、好ましくは、J kの比よりも小さいです
優れた優れた比k jをjのより3和[T]> G [I、J]> G [J、K] iが
I> J> K G [I、J] <G [j、k]はなら
kの1 G [I、J] <G [J、K] <和[T] J比iは、優れた優れたJよりも小さいです
2. G [I、J] <和[T] <G [J、K] iの優れた優れた比k jをjのより
優れた優れの3和[T] <G [I、J] <G [J、K] J比iのjはK
このような状況下で、jは確かに、除外されているので、私は後方から挿入された場合、そのときにフロントおよびJ、それが傾き数の勾配と以前の構成の数より少なく構成した場合、
まあ、これは確かに、Jではありません。
この合計が単調と接頭辞であるため、キューモノトーンDPを最適化することが可能です。
書式#include <cstdioを> する#include <CStringの> の#include <cstdlib> 書式#include <アルゴリズム> 書式#include <キュー> の#include <ベクトル> の#include <iostreamの> の#include < 文字列 > に#define INF 0x3f3f3f3f の#define inf64 0x3f3f3f3f3f3f3f3f 使用して 名前空間STD; const int型 MAXN = 1E5 + 10 。 typedefの長い 長いLL。 LL DP [ 1100 ] [ 1100 ]、合計[ 1100 ]、ヴァル[ 1100]、[ 1100 ]。 int型QUE [MAXN]。 LLアップ(int型 I、int型 J、int型K) { 戻り DP [I - 1 ] [J] -ヴァル[J] +和[J] *和[J] - (DP [I - 1 ] [K] -ヴァル[K] +和[K] * 和[K])。 } ダウン11(int型 J、int型K) { 戻り和[J] - 和[K]。 } LL DP(int型 I、int型 J、int型K) { 戻り DP [I - 1 ] [K] +ヴァル[J] -ヴァル[K] - (和[J] -和[K])*和[K ]; } int型のmain() { int型、N M。 一方、(scanf関数(" %d個の%のD "、&N、&M)&&(N + M)){ 合計[ 0 ] = 0 ; ヴァル[ 0 ] = 0 。 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %のLLDを"&[I])。 和[I] =和[I - 1 ] + [I]。 ヴァル[I] = valの[I - 1 ] +和[I - 1] * A [I]; } ため(INT I = 1 ; I <= N - 、Iは++)DP [ 1 ] [I] =ヴァル[I]; // なお、本主題の初期化 のために(INT I = 2、I <= M + 1 ; I ++ ){ int型のヘッド= 0、尾= 0 ; // 注DPは、[i、jは]定義の端部は、Iブロックの最小値にjは QUE [尾++] = I - 1。 ; / / 次のセグメントは、Iブロックに分割されるので、フロントの数は、少なくとも、I-1を占めていること、及びノートケースが欠落していない、全体に別の続くことができる ため(int型 J = I; J <= N; J ++ ){ // 私は開始これは見なければならないことに注意してくださいJ 一方、(ヘッド+ 1 <尾&&アップ(I、QUE [ヘッド+ 1 ]、QUE [頭部])<=和[J] *ダウン(QUE [ヘッド+ 1 ]、QUE [頭部]))ヘッド++ 。 DPは、[I] [J] = DP(I、J、QUE [ヘッド])。 一方、(ヘッド+ 1 <尾&&アップ(I、J、QUE [テイル- 1 ])*ダウン(QUE [テイル- 1 ]、QUE [尾- 2 ])<=最大(I、QUE [テイル- 1 ]、QUE [尾- 2 ])*ダウン(J、QUE [テイル- 1 ]))tail-- 。 QUE [テール ++] = J; } } のprintf("%LLD \ n "、DP [M + 1 ] [N]); } 戻り 0 ; }