AtCoder agc007_d Shik and Game

Luo Gu title page Portal & AtCoder title page Portal

There \ (1 \) root axes, Shik initial position \ (0 \) . There are a number line \ (n-\) bears, the \ (I \) only in the position \ (a_i \) . Shik per second can be moved leftward \ (1 \) unit lengths, stagnant or rightward \ (1 \) unit lengths. Shik first \ (1 \) times to the location of a bear \ (s \) after the second, the Cubs will be produced in situ \ (1 \) gold coins, Shik must reach this position again bear to collect coins. After seeking Shik after collecting all coins reaches the position \ (m \) takes the minimum number of seconds.

\(n\in\left[1,10^5\right],a_i\in(0,m),a_i<a_{i+1}\)

Consider the optimal case, Shik route would be like. If Shik after some bear, back part of the collection of coins behind these Cubs, and then continue to go to the end, leaving a portion of the front of the gold to wait until later to close, this is certainly not optimal (emotional understanding). If a can be introduced coins bear is received, then all of the coins bear preceding it are received, i.e. received bear a gold sequence is a prefix of all bear sequence. Consider a prefix into several time intervals, in each interval bear is in a back gold was received, so we can the DP.

Set \ (dp_i \) represents the former Shik have ended \ (i \) cubs gold coins and returned to the position \ (a_i \) The minimum number of seconds spent. You may assume \ (a_0 = 0 \) as a starting point. Boundaries are then clearly \ (dp_0 = 0 \) , the target is \ (m dp_n-A_N + \) . Before a Cubs left end point of the last section of the transfer, then the enumeration is currently being collected coins bear the prefix divided \ (j \) before, and last back \ ([1, j] \ ) has been received . Then back to the last received it is \ ([+ J. 1, I] \) . Clearly, this route is: before the first \ (J \) cubs harvested gold, returns to the position \ (a_j \) , then \ (a_j \ to a_i \) after \ ([j + 1, i ] \) so that they produce gold and \ (a_i \ to a_ {j + 1} \) back to the first \ (j + 1 \) cubs, wait several seconds until the \ (j + 1 \) cubs generate gold and \ (a_ {j + 1} \ to a_i \) sequentially harvested \ ([j + 1, i ] \) of gold and back to the position\ (a_i \) . Then the state transition equation on a good column:

\[dp_i=\min_{j=0}^{i-1}\left\{dp_j+(a_i-a_j)+(a_i-a_{j+1})+\max\left(0,s-2(a_i-a_{j+1})\right)+(a_i-a_{j+1})\right\}\]

which is

\[dp_i=\min_{j=0}^{i-1}\left\{dp_j+3a_i-a_j-2a_{j+1}+\max\left(0,s-2a_i+2a_{j+1}\right)\right\}\]

Transfer violence apparently \ (\ mathrm O (n ^ 2) \) , then consider optimizing. There is a noted equation \ (\ max \) is not treated, so the discussion classification, into \ (s-2a_i + 2a_ { j + 1} \ ge0 \) and \ (s-2a_i + 2a_ { j + 1 } <0 \) this \ (2 \) species. At this time, the equation becomes a :( after simplification)

\[dp_i=\min\left(\min_{j\in[0,i),s-2a_i+2a_{j+1}\ge0}\{dp_j+a_i-a_j+s\},\min_{j\in[0,i),s-2a_i+2a_{j+1}<0}\{dp_j+3a_i-a_j-2a_{j+1}\}\right)\]

About the decision variables \ (j \) is put together, with respect to the state variables \ (i \) and constant put together, too

\[dp_i=\min\left(\min_{j\in[0,i),2a_{j+1}\ge 2a_i-s}\{(dp_j-a_j)+(a_i+s)\},\min_{j\in[0,i),2a_{j+1}<2a_i-s}\{(dp_j-a_j-2a_{j+1})+3a_i\}\right)\]

\ (2 \) a \ (\ min \) condition in the \ (2a_ {j + 1} \) clearly monotony, so \ (2 \) a \ (\ min \) taken \ (J \ ) constitutes range. Particularly, for the first \ (2 \) a \ (\ min \) , a prefix, i.e., a left end point \ (0 \) interval. And because \ (2a_i-s \) has monotonicity, so the first \ (1 \) a \ (\ min \) interval left endpoint monotonically increasing, for each \ (I \) , the left end point may be two-pointers obtained. Thus for the first \ (1 \) a \ (\ min \) maintenance monotone queue for the first \ (2 \) a \ (\ min \) to maintain minimum prefix, \ (\ mathrm O (n-) \) .

Paste the code below:

#include<bits/stdc++.h>
using namespace std;
#define int long long//防爆int 
const int inf=0x3f3f3f3f3f3f3f3f;
const int N=100000;
int n/*小熊个数*/,m/*终点*/,s/*小熊被Shik碰到至生产金币之间的秒数*/;
int a[N+1];//小熊的位置 
int dp[N+1];//dp[i]表示Shik收完了前i个小熊的金币并回到了位置a[i]所花的最小秒数 
int q[N],head,tail;//对于第1个min维护的单调队列 
signed main(){
    cin>>n>>m>>s;
    for(int i=1;i<=n;i++)cin>>a[i];
    q[tail++]=0;//i=1,j=0满足2a[j+1]>=2a[i]-t,归第1个min,于是压入单调队列 
    int now=-1/*第2个min取的j构成的区间(前缀)的右端点*/,mn=inf/*当前的前缀最小值*/;
    for(int i=1;i<=n;i++){
        while(now+1<i&&2*a[now+2]<2*a[i]-s)now++,mn=min(mn,dp[now]-a[now]-2*a[now+1]);//将now往后移 
        while(head<tail&&q[head]<=now)head++;//维护单调队列,弹出过时元素 
        while(head<tail&&dp[q[tail-1]]-a[q[tail-1]]>=dp[i-1]-a[i-1])tail--;//维护单调队列队尾严格单调递增性 
        q[tail++]=i-1;//将j=i-1入队 
        dp[i]=min(dp[q[head]]-a[q[head]]+a[i]+s,mn+3*a[i]);//状态转移方程 
    }
    cout<<dp[n]+m-a[n]<<"\n";//目标 
    return 0;
}

Guess you like

Origin www.cnblogs.com/ycx-akioi/p/AtCoder-agc007-d.html