poj2018 Best Cow Fences[二分答案or斜率优化]

题目。


首先暴力很好搞,但是优化的话就不会了。放弃QWQ。

做法1:二分答案

然后发现平均值是$ave=\frac{sum}{len}$,这种形式似乎可以二分答案?把$len$移到左边。

于是二分$ave$,去找数列有没有区间和大于等于其$len$乘以$ave$的,然后卡住了。。

有一个很巧的转化,把每个数都减去一个$ave$,然后任意区间和就相当于把$ave$累加了$len$次。

于是乎只要看区间和$S-len*ave$是否大于等于0就可以了。

存在这样一个区间就说明$ave$可以更大,否则要小。查找存在性是一个简单的前缀和dp。

$O(nlogn)$。

poj精度死活卡不过去。

看来技巧还不够。

于是一气之下把所有double型全换成long long,也就是把小数点后五位通通看成整数,然后运算,最后除以100。

唉。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define dbg(x) cerr << #x << " = " << x <<endl
 7 using namespace std;
 8 typedef long long ll;
 9 typedef double db;
10 typedef pair<int,int> pii;
11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
16 template<typename T>inline T read(T&x){
17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
19 }
20 const int N=1e5+7;
21 const db eps=1e-7;
22 ll A[N],s[N];
23 ll L=1,R,mid;
24 int n,l;
25 inline bool check(ll ave){
26     for(register int i=1;i<l;++i)s[i]=s[i-1]+A[i]-ave;
27     ll minx=1e16;
28     for(register int i=l;i<=n;++i){
29         MIN(minx,s[i-l]);s[i]=s[i-1]+A[i]-ave;
30         if(s[i]-minx>=0)return 1;
31     }
32     return 0;
33 }
34 
35 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
36     read(n),read(l);
37     for(register int i=1;i<=n;++i)A[i]=read(A[i])*100000,MAX(R,A[i]);
38     while(L<R){
39         mid=L+R+1>>1;
40         if(check(mid))L=mid;
41         else R=mid-1;
42     }
43     printf("%lld",(L/100));
44     return 0;
45 }
View Code

做法2:斜率优化

猜你喜欢

转载自www.cnblogs.com/saigyouji-yuyuko/p/11458247.html