51 Nod 1281 山峰和旗子 (二分)
用一个长度为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
思路:思路简单
把所有山峰找出来 最后一个不能算!!! (因为右边没有比他小的山)
当然第一个也不能算
每次二分一个 mid 表示要插 mid 个旗子 检验是否可行
大佬竟然dp检验!! 我只会模拟检验了。。
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #define max(a,b) a<b?b:a 5 6 const int MAXN=50010; 7 8 int n,tot; 9 10 int a[MAXN],b[MAXN]; 11 12 inline void read(int&x) { 13 int f=1;register char c=getchar(); 14 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 15 for(;isdigit(c);x=x*10+c-48,c=getchar()); 16 x=x*f; 17 } 18 19 bool check(int x) { 20 int t=0,s=1; 21 for(int i=2; i<=tot; ++i) { 22 t+=b[i]-b[i-1]; 23 if(t>=x) ++s,t=0; 24 } 25 if(s>=x) return true; 26 return false; 27 } 28 29 int hh() { 30 read(n); 31 for(int i=1; i<=n; ++i) read(a[i]); 32 for(int i=2; i<n; ++i) if(a[i]>a[i-1] && a[i]>a[i+1]) b[++tot]=i; 33 34 int l=0,r=tot+1; 35 while(l+1<r) { 36 int mid=(l+r)>>1; 37 if(check(mid)) l=mid; 38 else r=mid; 39 } 40 41 printf("%d\n",l); 42 return 0; 43 } 44 45 int sb=hh(); 46 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现