[Algorithm stencil] Optimization slope

[Algorithm stencil] Optimization slope

In the previous blog, the optimized slope Jidao example. But those examples are the "state" as "segment" to deal with. Finally, I found, or the state as a point on a two-dimensional plane better deal.

Here a question yesterday to simulate race as example to talk about slope optimization.

ZROI- # 885- cat

Most of this article written by Harry_bh, would like to acknowledge.


\(Dp_{i,j}=Dp_{i-1,k}\)

\(dp_i=dp'_j+val(i-j)-(s_i-s_j)\)

Assuming that \ (j \) is the optimal decision point

Suppose \ (j <k \)

For any \ (K \) satisfy
\ [dp_j + val (ij) - (s_i-s_j) \ leq dp_k + val (ik) - (s_i-s_k) \\ dp_j-dp_k + s_j-s_k \ leq val (jk) \\ \ cfrac {dp_j -dp_k + s_j-s_k} {jk} \ geq val \\ \]

The meaning of what he is two points \ ((J, dp_j + S_j) \) , \ ((k, dp_k + S_k) \) the slope of the straight line formed

So if \ (J \) than \ (K \) better, then the slope satisfied. . . .

You maintain a queue, so we want to make the team first element is the optimal decision points we want, as the team set up the first element of that \ (the slope of the first point and the second point \ geq Val \) . And \ (Val \) is a monotonically increasing, so I need to make the door queue and each point on a point of the slope is a monotonically increasing (i.e., the convex hull).

We when inserting a new element to the tail, need to determine if \ (tail, tail-1 \ ) slope is larger than \ (insertion elements, tail-1 \) when the slope, it is necessary to \ (tail \) deleted out. (Specific, which means that \ (tail \) state and is not superior to insert an element in the nature of this queue is better than every team in the state of all the states behind him)

Code:

#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]);
}

Guess you like

Origin www.cnblogs.com/GavinZheng/p/11318982.html