修建传送门
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 76(18 users) Total Accepted: 19(16 users) Rating: Special Judge: No
Description
做为长城上的卫士,影踪派一直守在螳螂高原上防止螳螂人卡拉克西的入侵。影踪派的长城可以近似看做是一条直线上依次编号为1~N的N个基地组成,编号相邻的两个基地之间由长城相连接,而影踪派掌门祝踏岚所在的影踪禅院位于编号为1的基地。
祝踏岚发现,每次螳螂人只会选择长城上的一个基地进行猛烈的攻击,所以,祝踏岚每次都要从影踪禅院赶到被攻击的基地亲临前线指挥战斗。但是,在长城上移动是很耗时的,为了能更快的赶到任何一个可能被攻击的基地,祝踏岚决定修建一对传送门。
一对传送门由两个入口组成,它能实现在两个入口间的瞬间转移。出于安全考虑,这两个入口一定要建造在基地上。祝踏岚想选出两个合适的基地建造这一对传送门,使得他从影踪禅院赶到任何一个基地所需要的移动距离最远的那个最短。(每次祝踏岚都会选择采用最短的方式前往每一个基地)。你能帮助他么?
Input
第一行为一个正整数T,表示测试数据组数。
每组测试数据第一行为一个整数N(1 <= N <= 100000),第二行包含N-1个正整数,其中第i个数表示编号为i的基地与编号为i+1的基地之间的长城长度。此长度不会超过2147483647.
Output
对每组测试数据输出一行,仅含一个整数,表示按照最优方案建造完虫洞后,祝踏岚需要从基地1赶到的移动距离最远的基地的移动距离。
Sample Input
2
3
1 20
6
1 2 3 4 5
Sample Output
1
5
Source
2016级新生程序设计全国邀请赛
题解:首先很容易想到需要把一个传送阵建立在1位置。然后我们枚举另一个传送阵的位置,同时记录答案。又因为要求的是每次的最远距离。这个最远距离的目的地只有两种情况。一:两个传送门的中的某一点。二:最后一个点。所以在枚举传送阵(设为i)的同时,我们需要枚举这个”点”(设为l),又因为他会采用最短的方式去每一个点。我们硬性要求dis[1][l]小于dis[l][i]。则我们需要再比较dis[1][l]与dis[l+1][i](因为did[1][l]小于dis[l][i],所以没法确定dis[1][l],dis[l+1][i]的大小)。维和过程中的最大值和结果最小值。
代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#define ll long long
using namespace std;
ll dp[110000];
ll a;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=1;i<n;i++)
{
scanf("%lld",&a);
dp[i]=dp[i-1]+a;
}
ll ans=1e15;
int l=1;
for(int i=2;i<=n;i++)
{
ll sum=0;
while(l<i&&dp[i-1]-dp[l]>dp[l])l++;//这里维护的是dp[i-1]-dp[l-1]与dp[i-1]的关系。因为此时的“l”已经满足题意。我们想知道”l+1“是否满足
sum=max(dp[l-1],dp[i-1]-dp[l]);
sum=max(sum,dp[n-1]-dp[i-1]);
ans=min(ans,sum);
}
printf("%lld\n",ans);
}
}