B - ローレンスHDU - 2829は、スロープDP DP遷移方程式を書き込みません

B - ローレンス

 2829 - HDU 

ここでは、私は、この式で書いていないハード、ハード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 ; 
}

 

おすすめ

転載: www.cnblogs.com/EchoZQN/p/11402172.html