[USACO16JAN] Angry Cows G题解
题目描述
奶牛 Bessie 设计了一款她认为将成为下一个热门视频游戏的游戏:“愤怒的奶牛”。她认为这个游戏的设定是完全原创的:玩家用弹弓将一头奶牛射入一个一维场景中,场景由数轴上不同位置的干草堆组成;奶牛以足够的力量落地,引爆她着陆点附近的干草堆,这可能会引发连锁反应,导致更多的干草堆爆炸。目标是用一头奶牛引发连锁反应,引爆所有干草堆。
有 N 个干草堆位于数轴上不同的整数位置 x1,x2,…,xN。如果一头奶牛以威力 R 被发射到位置 x,这将引发一个“半径为 R”的爆炸,吞噬 x−R…x+R 范围内的所有干草堆。这些干草堆随后会同时爆炸,每个爆炸的半径为 R−1。任何尚未爆炸的干草堆如果被这些爆炸波及,则会同时爆炸,爆炸半径为 R−2,依此类推。
请确定发射一头奶牛所需的最小威力 R,使得如果它落在适当的位置,将引发所有干草堆的爆炸。
输入格式
输入的第一行包含 N(2≤N≤50,000)。接下来的 N 行每行包含一个整数 x1…xN(每个整数都在 0…1,000,000,000 范围内)。
输出格式
请输出发射奶牛所需的最小威力 R,以便引爆所有干草堆。答案应四舍五入并精确到小数点后一位。
显示翻译
题意翻译
输入输出样例
输入 #1复制
5 8 10 3 11 1
输出 #1复制
3.0
说明/提示
在这个例子中,一头奶牛以威力 3 发射到位置 5,将立即引爆位置 3 和 8 的干草堆。这些干草堆随后同时爆炸,每个爆炸的半径为 2,吞噬位置 1 和 10 的干草堆,这些干草堆接下来同时爆炸,爆炸半径为 1,吞噬位置 11 的最后一个干草堆,该干草堆最终以爆炸半径 0 爆炸。
思路
DP即可。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,x[50004],f[50004],g[50004];
long long abc(double a1){
for(int i=n;i>=1;i--){
if(f[i]+1<=a1){
for(int j=i;j<=n&&x[j]<=x[i]+2.0*a1;j++){
if(g[j]+1<=a1){
return 1;
}
}
break;
}
}
return 0;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];
}
sort(x+1,x+n+1);
for(int i=2;i<=n;i++){
long long l=1,r=i-1,md=i-1;
while(l<=r){
long long mid=(l+r)/2;
if(x[i]-x[mid]<=f[mid]+1){
md=min(md,mid);
r=mid-1;
}
else{
l=mid+1;
}
}
f[i]=max(x[i]-x[md],f[md]+1);
if(md!=1){
f[i]=min(f[i],max(x[i]-x[md-1],f[md-1]+1));
}
}
for(int i=n-1;i>=1;i--){
long long l=i+1,r=n,md=i+1;
while(l<=r){
long long mid=(l+r)/2;
if(x[mid]-x[i]<=g[mid]+1){
md=max(md,mid);
l=mid+1;
}
else{
r=mid-1;
}
}
g[i]=max(x[md]-x[i],g[md]+1);
if(md!=n){
g[i]=min(g[i],max(x[md+1]-x[i],g[md+1]+1));
}
}
double l=0,r=1000000000.00,md=1000000000.00;
while(l+0.0001<r){
double mid=(l+r)/2.000;
if(abc(mid)==1){
md=min(md,mid);
r=mid;
}
else{
l=mid;
}
}
printf("%.1lf\n",md);
return 0;
}

浙公网安备 33010602011771号