POJ 1759 Garland 二分答案

题意

  • 题目背景是在绳上挂灯。。我觉得完全不用鸟这个背景。。。
  • 它表达的核心意思,就是一个数列告诉你首项h1, 项数n,递推式hi = (hi+1 + hi-1 ) / 2 - 1
  • 在保证hi都大于等于0的前提下,让hn最小

思路

  • 这题不难想到可以使用二分,但是二分哪个变量,找到哪样的单调关系需要考虑一下。
  • 首先,通过题目给出的递推式,很容易得到标准的递推形式: hi+1 = 2hi - hi-1 + 2
  • 这样,我们就知道,只要确定了h2,hn肯定就确定了,所以我们二分的变量就是h2了
  • 接下来,我们从递推式入手,来找单调关系
  • 假如递推式为:hi = (hi+1 + hi-1 ) / 2,那会有怎样的结果呢?不难想象,当h2确定时,整个数列就是一个等差数列了,所以数列肯定是单调的。
  • 而如果hi在这个基础上减一呢?不难想象,在hi+1 < hi-1时,hi位于两个数等分位偏hi+1的位置一些,而在hi+1 > hi-1时,hi位于两个数等分位偏hi-1的位置一些。所以在h2 < h1的情况下,整个数列画出的图像一定是先单调递减,但递减幅度越来越小,直至幅度减到足够小,然后递增,并且递增幅度越来越大的过程。
  • 因此,我们的单调关系就是,f(h2): hi是否都大于等于0
  • 另外,这个递推式,通过迭代几次找规律的方法,也不能得出通项公式,不过这个通项公式并不影响整体复杂度,所以这里不多提了,代码里用了一下~
  • 注意:poj上如果用g++,输出不能用%lf,否则WA,要用%f。这个原因我也不是很明白,如果有路过的大神,也望指点一下~~

实现

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int n;
double A;
const double eps = 1e-6;
bool judge(double a1, double a2){
    for (int i=3;i<=n;i++){
        a1 = 2 * a2 - a1 + 2;
        if (a1 < 0)
            return false;
        swap(a1, a2);
    }
    return true;
}
int main(){
    cin>>n>>A;
    double l = 0, r = A, a = 0;
    int T = 100; 
    while (T--){
        double mid = (r+l) / 2;
        if (judge(A, mid)){
            r = mid;
            a = mid;
        }
        else{
            l = mid;
        }
    }
    double a1 = A, a2 = a;
    printf("%.2f\n",(n-1) * a2 - (n-2) * a1 + (n-1) * (n-2));
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值