poi2014 Freight

Freight

The train stations in Upper Bytown and Lower Bytown are connected with a single track rail link. It takes the train   minutes to travel between them in either direction. However, the trains departing a station have to be spaced at least one minute apart. Moreover, at all times, all the trains on the rail link have to go in the same direction.

According to the timetable at our disposal,   cargo trains destined for Lower Bytown are to pass through the Upper Bytown. They are to be loaded with goods in Lower Bytown and then return to Upper Bytown. For simplicity, we assume that loading the goods on the train takes virtually no time.

We are to determine the minimum possible time of the last train returning to Upper Bytown.

 

 

输入

 

The first line of the standard input contains two integers N,S(1<=N<=1 000 000,1<=S<=10^9) , separated by a single space, that specify the number of trains and the one-way travel time respectively.

 

The second line contains   integers T1,T2…Tn(0<=T1<=T2..<=Tn<=10^9) , separated by a single space, that specify the arrival times of successive trains at the Upper Bytown station.

 

 

输出

 

Your program should print out a single line with a single integer to the standard output: the minimum possible time of the last train returning to Upper Bytown.

 

 

样例输入

3 4
1 8 11

样例输出

20

提示

 

 

 

 

来源

poi2014


solution

可以看出车是一批批回来的,不会在那等。

那么考虑dp

f[i]=min(max(a[i],f[j]+i-j-1)+2*s+i-j-1)

把a[i]取成max(a[i],a[i-1]+1) 不影响答案

且保证了a[i]>f[j]+i-j-1 时 转移递增

又因为a[i]<f[j]+i-j-1时f[i] 时 转移递增  (f[j]>2*j)
所以转移成一个V型

 

找到那个点即可

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 1000006
using namespace std;
int n,a[maxn];
long long f[maxn],S;
int main(){
    cin>>n>>S;
    a[0]=-1;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[i]=max(a[i],a[i-1]+1);
        f[i]=1e15;
    }
    int j=1;
    for(int i=1;i<=n;i++){
        while(j<i&&f[j]+i-j-1<a[i])j++;
        f[i]=min(f[i],a[i]+2*S+i-j);// 其实是向j-1转移
        if(f[j]+i-j-1>=a[i])f[i]=min(f[i],f[j]+i-j-1+2*S+i-j-1);
    }
    cout<<f[n]<<endl;
    return 0;
}

 

posted @   liankewei123456  阅读(101)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示