首页 > 其他 > 详细

2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Journey to the "The World's Start"

时间:2020-11-18 21:29:31      阅读:28      评论:0      收藏:0      [点我收藏+]

首先我们二分一个x,x是用的票能跳过x站,因为票可以多次使用,所以我们要dp当第i站能用票省下的时间p,只要p小于等于 (不用票的总时间-t)就好了
这个dp我们可以写出转移方程 dp[i]=\(max_{j=i-x}^{j=i}\)(d[j]+s[i]-s[j],(s是前缀和)
但是这个dp是\(n^2\)的,所以我们需要用单调队列优化
代码

#include<stdio.h>
#define LOCAL
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5+10;
ll p[maxn],d[maxn],a[maxn],dp[maxn],q[maxn];ll n,t,sum,mi=1e9;
ll pd(ll mid)
{
    memset(q,0,sizeof(q));ll l=1,r=0,mx=0;
    memset(dp,0,sizeof(dp));
    q[++r]=1;
    for(ll i=2;i<=n;i++)
    {
        while(l<=r&&(i-q[l])>mid) l++;
        //printf("i=%lld q[%lld]=%lld\n",i,l,q[l]);
        dp[i]=dp[q[l]]+a[i-1]-a[q[l]];
        mx=max(dp[i],mx);
        while(l<=r&&(dp[i]-a[i]>=dp[q[r]]-a[q[r]])) r--;
        q[++r]=i;
        //printf("dp[%lld]=%lld q[%lld]=%lld  q[%lld]=%lld\n",i,dp[i],l,q[l],r,q[r]);
    }
    if(mx>=sum) return 1;
    return 0;
}
int main()
{
#ifdef LOCAL
    freopen("journey.in","r",stdin);
	freopen("journey.out","w",stdout);
#endif

	scanf("%lld %lld",&n,&t);
	sum=n-1;
	for(int i=1;i<=n-1;i++)
	{
		scanf("%lld",&p[i]);mi=min(p[i],mi);
	}
	for(int i=2;i<=n-1;i++) scanf("%lld",&d[i]),sum+=d[i];
	if(sum<=t)
	{
		printf("%lld\n",mi);
		return 0;
	}
	sum=sum-t;
	ll l=1,r=n-1,len=0;
	for(ll i=2;i<=n;i++) a[i]=a[i-1]+d[i];
	//pd(1);
	while(l<=r)
    {
        ll mid=(l+r)/2;
        if(pd(mid)==1)
        {
            len=mid;
            r=mid-1;
        }
        else l=mid+1;
    }
    ll g=1e9;
    for(int i=len;i<=n-1;i++) g=min(g,p[i]);
    printf("%lld\n",g);
	//printf("sum=%d\n",sum);
	/*ll s=0,l=1,r=1;
	ll len = n+10;
	while(l<=r&&l<=n-1&&r<=n)
	{
		int flag=0;
		while(s<sum){
			s+=1+d[r];
			r++;
			if(r>n){
				flag=1;
				break;
			}
		}
		if(flag==1)break;
		len=min(len,r-l);
		printf("s=%lld l=%lld r=%lld\n",s,l,r);
		if(l+1<r)
		s-=d[l+1]+1;
		else s--;
		l++;
	}
	printf("len=%lld\n",len);
	ll g = 1e9;
	for(ll i = len; i <= n-1; i++){
		g=min(g,p[i]);
	}
	printf("%lld\n",g);*/

}
/*
4 4
1 2 3
1 4

6 6
1 4 5 5 6
7 1 5 6

*/

2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Journey to the "The World's Start"

原文:https://www.cnblogs.com/League-of-cryer/p/14001826.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!