最近有人问我这个题这么做,光讲几句貌似没什么用,干脆发个题解吧(话说什么有人会来问我这个蒟蒻)
题面的意思大概就是说每个点的高度都和旁边2个点有关,整张图没有高度小于0的点,求最后一个点B的最低值
是不是长得像个数学题?所以我们用数学的方法来思考一下Hi怎么得出。
题目中说过,Hi = (H[i?1] + H[i+1])/2-1,也就是已知旁边的2个点,就可以求出中间的点2,因为表达式已知,所以我们可以通过其中2个点求出第3个点。
简单地推一推:设第1个点为a,第2个点为b,第3个点为c,已知a,b。
∵b=(a+c)/2-1;
∴2b+2=a+c
∴2b+2-a=c
这样一来,我们就可以通过前面的点直接推出后面的点了!所以我们就只需要找出使B最低并且每个点都>=0的第2个点就可以了qwq
现在我们已经知道了B点的高度和第2点相关了,但是要求出B的最低的值,该怎么确定第2个点的值呢?
遇到这种在条件中求最值问题,首先想到的肯定是二分。因为二分可以不断地缩小查找范围,最终缩小到不满足条件与满足条件之间,也就是最浪小的值了。
细节部分直接看代码:
#include<bits/stdc++.h>
using namespace std;
const double mina=1e-6;
int n;
double a,l,r,mid,lp[1010];
bool judge(double x)//每次二分暴力的判断一下是否有点小于0
{
lp[1]=a;
lp[2]=x;
for(int i=3;i<=n;i++)
{
lp[i]=2*lp[i-1]-lp[i-2]+2;
if(lp[i]<0)return false;
}
return true;
}
int main()
{
while(scanf("%d%lf",&n,&a)!=EOF)//这句话记住就好,貌似只在洛古上有用(哪位大佬告诉我是不是Linux的原因)
{
for(int i=0;i<=1009;i++)lp[i]=0.00;
l=a/2-1;//这里可以优化一下二分的范围,因为这个值刚好使第3个点为0
r=a;//随便设个高一点的值即可
while(r-l>mina)//保证精度
{
mid=(l+r)/2;
if(judge(mid)==true)r=mid;//满足的话就可以再小一点
else l=mid;//不满足的话就增大
}
printf("%0.2lf\n",fabs(lp[n]));
getchar();//读走回车
}
return 0;
}//看懂了记得点赞QWQ
原文地址:https://www.cnblogs.com/Hdgs3-blog/p/10327668.html
时间: 2024-10-14 12:03:35