zoukankan      html  css  js  c++  java
  • JSOI2016 灯塔

    JSOI2016 灯塔

    题面描述

    JSOI的国境线上有(N)座连续的山峰其中第(i)座的高度是(h_i).为了简单起见,我们认为这(N)座山峰排成了连续一条直线。

    如果在第(i)座山峰上建立一座高度为(p)((pge0))的灯塔, JYY发现,这座灯塔能够照亮第(j)座山峰当且仅当满足如下不等式:

    [h_jle h_i+p-sqrt{|i-j|} ]

    JSOl国王希望对于每一座山峰, JYY 都能提供建造一座能够照亮全部其他山峰的灯塔所需要的最小高度。 你能帮助JYY么?

    思路

    先移项。

    [h_j+sqrt{|i-j|}-h_ile p ]

    对于固定的(i),(-h_i)不用管,我们只需要就前面那一串的最大值就可以了。

    显然,(y=sqrt{x})是一个上凸函数,它增长的速度在逐渐减缓。

    也就意味着,如果一个前面的塔被后面的打败了,他就再也没有机会翻身了。

    所以,这道题具有决策单调性。

    二分解决即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int sz=1e5+7;
    int n;
    int h[sz];
    int pos[sz];
    int ans[sz];
    void solve1(int l,int r,int pl,int pr){
    	if(l>r) return;
    	int t=0;
    	double height=0;
    	int mid=(l+r)>>1;
    	for(int i=min(pr,mid-1);i>=pl;i--)
    	if(sqrt(mid-i)+h[i]>height){
    		height=sqrt(mid-i)+h[i];
    		t=i;
    	}
    	pos[mid]=t;
    	int k=ceil(height);
    	ans[mid]=max(ans[mid],k);
    	solve1(l,mid-1,pl,t);
    	solve1(mid+1,r,t,pr);
    }
    void solve2(int l,int r,int pl,int pr){
    	if(l>r) return;
    	int t=0;
    	double height=0;
    	int mid=(l+r)>>1;
    	for(int i=max(mid+1,pl);i<=pr;i++)
    	if(sqrt(i-mid)+h[i]>height){
    		height=sqrt(i-mid)+h[i];
    		t=i;
    	}
    	pos[mid]=t;
    	int k=ceil(height);
    	ans[mid]=max(ans[mid],k);
    	solve2(l,mid-1,pl,t);
    	solve2(mid+1,r,t,pr);
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&h[i]);
    	solve1(1,n,1,n);
    	solve2(1,n,1,n);
    	for(int i=1;i<=n;i++){
    		printf("%d
    ",max(ans[i]-h[i],0));
    	}
    }
    
  • 相关阅读:
    LeetCode 40. Combination Sum II
    LeetCode 39. Combination Sum
    #Python学习#python虚拟环境——virtualenv
    #阿里云#云服务器部署Django(基础篇)
    驱动调试之打印
    Linux内核源码阅读记录一之分析存储在不同段中的函数调用过程
    uevent机制
    字符设备的另一种写法
    DM9000C网卡驱动程序编写与测试
    网卡驱动程序框架以及虚拟网卡驱动程序的实现
  • 原文地址:https://www.cnblogs.com/river-flows-in-you/p/11987423.html
Copyright © 2011-2022 走看看