一般这种求什么最大中的最小或者最小中的最大,差不多都要用到二分法。
既然已经知道用什么就简单了,注意A序列没有负数但是B序列可以有负数。
我们函数 judgefail(int curr) 来判断当最大代价为curr时该序列是否可以变成严格单调。
judgefail函数直接模拟就好,只要使后面一个元素尽量的接近前面一个元素即可。
对于第一个元素,当然是越小越好。
设x=0,s=1000000,curr=(x+s)/2,然后开始二分。当s-x<=1的时候在判断一下,得出结果。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int arr[100005];
int N;
int judgefail(int curr)
{
int fail=0;
int fro=arr[1]-curr;
for(int i=2;i<=N;i++)
{
if(arr[i]<=fro)
{
int dis=fro-arr[i];
if(dis>=curr)
{
fail=1;
break;
}
else
fro=fro+1;
}
else
{
int dis=arr[i]-fro;
if(dis>curr)
fro=arr[i]-curr;
else
fro=fro+1;
}
}
return fail;
}
int main()
{
int T;
cin>>T;
for(int Case=1;Case<=T;Case++)
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&arr[i]);
int s=1000000,x=0;
int curr=(x+s)/2;
int fail,fro;
int ans;
while(1)
{
if(judgefail(curr))
{
x=curr;
curr=(x+s)/2;
}
else
{
s=curr;
curr=(x+s)/2;
}
if(s-x<=1)
{
if(!judgefail(x))
ans=x;
else
ans=s;
break;
}
}
printf("Case #%d:\n%d\n",Case,ans);
}
}