zoukankan      html  css  js  c++  java
  • 51nod 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

    思路:二分+dp-------用一个f[]数组保存山峰的位置,首先如果没有山峰则直接输出0,其次距离越大代表我们要插的旗子数就越大,我们枚举旗子的个数k 找到最大的可行方案;当然直接枚举会超时,所以这里需要用二分来枚举;
       对于每一个k我们需要用一次dp数组来遍历一次,dp[i]代表前i个位置能插入距离为k的旗子的个数;我们可以得到递推公式 若当前位置不可以插旗子dp[i] = dp[i-1];否则dp[i] = max(dp[i-k]+1,dp[i]);
       其中i-k>0;遍历完之后若dp[n-1]>=k说明我们的k还可以继续增大,直到dp[n-1]恰好等于k的时候就停止二分,此时的k即为最大值
     
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 typedef long long LL;
     7 const int maxn = 50005;
     8 LL n,a[maxn],f[maxn],d[maxn];;
     9 int main()
    10 {
    11     ios::sync_with_stdio(false);
    12 //    freopen("in.txt","r",stdin);
    13     while(cin>>n){
    14         int flag = 0;
    15         for(int i=0;i<n;i++)cin>>a[i];
    16         for(int i=1;i<n-1;i++)
    17             if(a[i]>a[i-1]&&a[i]>a[i+1]){
    18                 f[i] = 1;flag++;
    19             }
    20         if(!flag){
    21             cout<<"0"<<endl;
    22             continue;
    23         }
    24         int l=0,r=n,ans=0;
    25         while(l<r){
    26             int k = (l+r)>>1;
    27             for(int i=0;i<n;i++)
    28                 d[i] = f[i];
    29             for(int i=0;i<n;i++){
    30                 if(!f[i])d[i]=d[i-1];
    31                 else if(i-k>0) d[i] = max(d[i-k]+1,d[i]);
    32             }
    33             if(d[n-1]>=k){
    34                 ans = k;
    35                 l = k+1;
    36             }else r = k;
    37         }
    38         cout<<ans<<endl;
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    树莓派控制Arduino
    树莓派的基本配置
    OneNet的产品创建和支持协议
    云平台基本认知(OneNet)
    初识Arduino
    NEFU-大二大三训练赛17C-最大值
    NEFU-大二大三训练赛17D-泡泡堂
    pb数据导出
    PB窗口根据分辨率的大小调整窗口大小
    PowerBuilder常用字符串函数
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/9432927.html
Copyright © 2011-2022 走看看