zoukankan      html  css  js  c++  java
  • 51nod 1281 二分

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1281

    题目来源: Codility
    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
    收藏
    关注
    用一个长度为N的整数数组A,描述山峰和山谷的高度。山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]。
     
     
    现在要在山峰上插上K个旗子,并且每个旗子之间的距离 >= K,问最多能插上多少个旗子(即求K的最大值)。两个山峰之间的距离为|P - Q|。
    以上图为例,高度为:1 5 3 4 3 4 1 2 3 4 6 2。其中可以作为山峰的点为:1 3 5 10。
     
    放2面旗子, 可以放在1 和 5。
    放3面旗子, 可以放在1 5 和 10。
    放4面旗子, 可以放在1 5 和 10,之后就放不下了。
    所以最多可以放3面旗子。
    Input
    第1行:一个数N,表示数组的长度(1 <= N <= 50000)。
    第2 - N + 1行:每行1个数Ai(1 <= Ai <= 10^9)。
    Output
    输出最多能插上多少面旗子(即求K的最大值)。
    Input示例
    12
    1 
    5 
    3 
    4 
    3 
    4 
    1 
    2 
    3 
    4 
    6 
    2
    Output示例
    3

    显然可以枚举K值,至于判断K是否可行,把第一个山峰看作必放旗子然后往后贪心遇见可以放的位置就放就能找到最大的可放置旗子数,形如时间安排的证明过程假设最优解不包含第一个山峰,会发现第一个山峰包含显然优于不包含。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int h[50005];
     4 vector<int>vi;
     5 bool ok(int k)
     6 {
     7     int s=1,pre=vi[0];
     8     for(int i=1;i<vi.size();++i)
     9     {
    10         if(vi[i]-pre>=k){
    11             s++;
    12             pre=vi[i];
    13         }
    14     }
    15     if(s>=k) return 1;
    16     return 0;
    17 }
    18 int main()
    19 {
    20     int N,i,j;
    21     cin>>N;
    22     for(i=1;i<=N;++i) scanf("%d",h+i);
    23     for(i=2;i<N;++i)
    24         if(h[i]>h[i-1]&&h[i]>h[i+1]) vi.push_back(i);
    25     int l=0,r=vi.size();
    26     while(l<r){
    27         int mid=r-(r-l)/2;
    28         if(ok(mid)) l=mid;
    29         else r=mid-1;
    30     }
    31     cout<<l<<endl;
    32     return 0;
    33 }
  • 相关阅读:
    Pycharm
    Python
    navicat连接MySQL8.0出现2059错误
    MySQL Community Server 8.0.11下载与安装配置
    pip升级以及导入模块
    pycharm安装
    python环境安装
    js 超级玛丽(未完成)
    js 点名
    js 获取鼠标位置坐标
  • 原文地址:https://www.cnblogs.com/zzqc/p/7448065.html
Copyright © 2011-2022 走看看