2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest J - Journey to the "The World's Start"
题意:一共n个站,首先处于第一个站的乘车点,在不用卷的情况下,会花一分钟时间到下一站i+1站下车点,同时要花d[i]分钟到i+1站的乘车点,在用卷的情况下,假如用的是第r张卷,可以从i搭到i-r到i+r范围内的所有站台,乘车时间不能省略,但是跑去乘车点的时间可以省略,第r张卷需要p[r]元,一张卷可以用多次,问买哪一张卷可以在t时间内到达第n个站台。
题解:因为用第r张卷的时间一定要大于等于用r+1张卷的时间,所有可以二分用哪张卷,设dp[i]为到达第i站乘车点用的最短时间,dp[i]可以由i-r到i-1的dp的最大值得到,用双指针维护一下递减序列,与i距离大于r的踢出,头部比dp[i]值小的踢出,最后可得到dp[n]
http://codeforces.com/gym/100801
#include<stdio.h>
#include<algorithm>
using namespace std;
#define LOCAL
#define ll long long
ll p[50100],d[50100];
ll dp[50100],que[50100];
ll n,t;
int check(int k){
dp[1]=0;
que[1]=1;
int head=1,tail=1;
for(int i=2;i<=n;i++){
while(head>tail){
if(i-que[tail]<=k)break;
tail++;
}
dp[i]=dp[que[tail]]+d[i];
while(head>=tail){
if(dp[que[head]]<dp[i])break;
head--;
}
que[++head]=i;
//printf("que[head]=%d que[tail]=%d dp[%d]=%d\n",que[head],que[tail],i,dp[i]);
}
if(dp[n]+n-1>t)return 0;
else return 1;
}
int main(){
#ifdef LOCAL
freopen("journey.in","r",stdin);
freopen("journey.out","w",stdout);
#endif
scanf("%lld %lld",&n,&t);
for(int i=1;i<n;i++){
scanf("%lld",&p[i]);
}
for(int i=2;i<n;i++)scanf("%lld",&d[i]);
ll ans=n-1;
ll l=1,r=n-1;
//printf("%d\n",check(2));
while(l<=r){
int mid=(l+r)/2;
if(check(mid)==1){
ans=mid;
r=mid-1;
}
else{
l=mid+1;
}
}
ll res=100010;
for(int i=ans;i<n;i++)res=min(res,p[i]);
printf("%lld\n",res);
}

浙公网安备 33010602011771号