[アルゴリズムステンシル]最適化スロープ

[アルゴリズムステンシル]最適化スロープ

前回のブログでは、斜面Jidao例を最適化。しかし、これらの例は、に対処するための「セグメント」として「状態」です。最後に、私は、二次元平面よりよい取引上の点として求め、または状態。

スロープの最適化について話を例としてレースをシミュレートするために、ここで質問昨日。

ZROI-#885-猫

Harry_bhによって書かれたこの記事のほとんどは、承認したいと思います。


\(Dp_ {I、J} = Dp_ {I-1、K} \)

\(dp_i = dp'_j +ヴァル(IJ) - (S_I-s_j)\)

仮定すると、\(j個\)は、最適な意思決定ポイントであります

仮定(<K \ J)\

いずれかのために\(K \)満足
\ [dp_j +ヴァル(IJ) (S_I-s_j)\当量dp_k +ヴァル(IK) - - (S_I-S_K)\\ dp_j-dp_k + s_j-S_Kの\の当量のValを(JK)\\ \のcfrac {dp_j -dp_k + s_j-S_K} {JK} \ GEQヴァル\\ \]

彼は、2つの点で何の意味\((J、dp_j + S_j)\) \((K、dp_k + S_K)\)に形成された直線の傾き

その場合は\(J \)より\(K \) その後、より良い、スロープ満足。

あなたは、キューを維持するので、我々はチームがその最初の要素の設定としてチーム最初の要素は、私たちが望む最適な意思決定ポイントであるようにしたい\(最初のポイントの斜面と第2の点\ GEQヴァル\を)そして\(ヴァル\)が単調に増加しているので、私は斜面の点にドアキューと各ポイントを作るために必要なのは、単調増加(すなわち、凸包)です。

我々かどうかを決定する必要がある、末尾に新しい要素を挿入する\(尾部、尾-1 \ ) 傾きがより大きい\(挿入エレメント、テール1 \)勾配は、する必要がある場合(尾を\)\削除アウト。(具体的な、ということを意味している\(尾\)状態とは、このキューの自然の中で要素を挿入することが優れていないが、彼の背後にあるすべての状態の状態ですべてのチームよりも優れています)

コード:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define maxn (int)(1e5+100)
ll dp[1005][50020],dis[maxn],tim[50020],n,m,p,pre[maxn],h[maxn],t[maxn],queue[maxn];
using namespace std;
int main() {
    scanf("%lld%lld%lld",&n,&m,&p);
    for(int i=2;i<=n;i++){scanf("%lld",&dis[i]);dis[i]+=dis[i-1];}
    for(int i=1;i<=m;i++){scanf("%lld%lld",&h[i],&t[i]);tim[i]=t[i]-dis[h[i]];}
    sort(tim+1,tim+1+m);for(int i=1;i<=m;i++)pre[i]=tim[i]+pre[i-1];
    memset(dp,0x3f,sizeof(dp));dp[0][0]=0;
    for(int i=1;i<=p;i++) {
        ll head=1,tail=0;
        for(int j=0;j<=m;j++) {
            while(head<tail&&(dp[i-1][queue[head]]+pre[queue[head]]-dp[i-1][queue[head+1]]-pre[queue[head+1]])>tim[j]*(queue[head]-queue[head+1]))head++;
            dp[i][j]=dp[i-1][queue[head]]+tim[j]*(j-queue[head])-(pre[j]-pre[queue[head]]);
            while(head<tail&&(dp[i-1][queue[tail-1]]+pre[queue[tail-1]]-dp[i-1][queue[tail]]-pre[queue[tail]])*(queue[tail-1]-j)>(dp[i-1][queue[tail-1]]+pre[queue[tail-1]]-dp[i-1][j]-pre[j])*(queue[tail-1]-queue[tail]))tail--;
            queue[++tail]=j;
        }
    }
    printf("%lld",dp[p][m]);
}

おすすめ

転載: www.cnblogs.com/GavinZheng/p/11318982.html