Skip to content

14157: 【原4157】水灯节

题目

题目描述

author: Yifan 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4157

Description

水灯节到了,面包正忙着挂水灯。现在有n个水灯依次挂在一条绳子上,第i个水灯离地面的高度是\(H_i\)(\(H_i\)是实数)。由于重力的缘故,每个水灯的高度比左右相邻水灯高度的平均值低1个高度单位,即对任意\(1 < i < n\),\(H_i = \frac{H_{i - 1} + H_{i + 1}}{2} - 1\)。规定水灯不能触地,即任意\(1 \le i \le n\),\(H_i \ge 0\)。现在已知\(H_1\),求\(H_n\)的最小值。

Input Format

一行,一个正整数n和一个实数\(H_1\)。

Output Format

一个实数,表示\(H_n\)的最小值。

Sample Input

8 15

Sample Output

9.75

Data Range

对于20%的数据,\(3 \le n \le 10\),\(10 \le H_1 \le 100\)。

对于50%的数据,\(3 \le n \le 100\),\(10 \le H_1 \le 500\)。

对于100%的数据,\(3 \le n \le 1000\),\(10 \le H_1 \le 1000\)。

Hint

第二个水灯是面包最喜欢的,所以他很在意把第二个水灯挂多高。

zqy2018's solution

#include <bits/stdc++.h>
#define INF 2000000000
using namespace std;
typedef long long ll;
int read(){
    int f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
    while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
    return f * x; 
}
int n;
double h1;
ll a[1005], b[1005], c[1005];
void init(){
    n = read();
    cin >> h1;
    a[1] = c[1] = 0, b[1] = 1;
    a[2] = 1, b[2] = c[2] = 0;
}
void solve(){
    double h2 = 0;
    for (int i = 3; i <= n; ++i){
        a[i] = 2 * a[i - 1] - a[i - 2], 
        b[i] = 2 * b[i - 1] - b[i - 2], 
        c[i] = 2 * c[i - 1] - c[i - 2] + 2;
        h2 = max(h2, (-b[i] * h1 - c[i]) / a[i]);
    }
    double res = a[n] * h2 + b[n] * h1 + c[n];
    printf("%.2lf\n", res);                     // warning
}
int main(){
    init();
    solve();
    return 0;
}