POJ 1759 Garland

高度之间的关系可以改写成一个递推式:Hi+1 = 2Hi - Hi-1 + 2。Hn和Hi之间是正相关的。

思路见注释。(一开始是那么想的,其实不用矩阵快速幂,二分H2也可以。

/*********************************************************
*            ------------------                          *
*   author AbyssalFish                                   *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<numeric>
using namespace std;


/*
Hi = (Hi-1+Hi+1) /2 - 1
Hi+1 = 2Hi - Hi-1 + 2
构造 matrix
Hi+1 |2 -1 2 | Hi
Hi  =|1  0 0 | Hi-1
1    |0  0 0 | 1
Hn一定是H1和H2的线性组合
矩阵快速幂以后,根据Hn求出H2
然后就可递推了

*/

#define check_mat(M)\
for(auto r: M){\
        for(auto e: r) cout<<e<<' ';\
        cout<<endl;\
    }

typedef vector<int> row;
typedef vector<row> mat;
const int n = 3;
mat operator *(mat&A, mat &B)
{
    mat R(n,row(n));
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            for(int k = 0; k < n; k++){
                R[i][j] += A[i][k]*B[k][j];
            }
        }
    }

    return R;
}

mat operator ^(mat A, int q)
{
    mat R(n,row(n));
    for(int i = 0; i < n; i++) R[i][i] = 1;

    while(q){
        if(q&1) {
            R = R*A;
        }
        A = A*A;
        q >>= 1;
    }
    return R;
}

const int MAX_N = 1e3;
int N;
double A;
double H[MAX_N];
mat M(n,row(n));

#define check_var(v) cout<<v<<endl;

bool P(double Hn)
{
    H[1] = (Hn - M[0][1]*H[0] - M[0][2])/M[0][0];

    if(H[1] < 0.) return false;
    for(int i = 2; i < N-1; i++){
        H[i] = 2*H[i-1] - H[i-2] + 2;
        if(H[i] < 0.) {
            //check_var(H[i])
            return false;
        }
    }
    return true;
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    M[0][0] = 2; M[0][1] = -1; M[0][2] = 2;
    M[1][0] = 1; M[2][2] = 1;
    scanf("%d%lf", &N, H);
    M = M^(N-2);
    //check_mat(M)
    double lb = 0, ub = 1e9, md;

    for(int i = 100; i--;){
        md = (lb+ub)/2;
        P(md) ? ub = md: lb = md;
    }
    printf("%.2f",(lb+ub)/2);
    return 0;
}

 

posted @ 2015-11-21 11:55  陈瑞宇  阅读(317)  评论(0编辑  收藏  举报