P1404 平均数
P1404 平均数
这个题有点像01分数规划那种类型。
二分值域,逼近答案
对于二分中的每次循环,有一个很巧妙的前缀最小记录,就是这个:Min=min(Min,s[i-m])
一直往后扫,对于大于当i>=m时,考虑 if(s[i]-Min>=0),是的话一定有满足当前mid的区间(也就是有限制的最大子段和)
对于找平均数的问题,一般可以二分答案解决
ps:现在遇到1e5的数据范围总是陷在考虑O(n)的做法上,这个题是一个启发吧
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+5; 5 int n,m; 6 ll a[maxn]; 7 ll s[maxn]; 8 int main() 9 { 10 std::ios::sync_with_stdio(false); 11 cin>>n>>m; 12 ll M=0; 13 for(int i=1;i<=n;i++) 14 { 15 cin>>a[i]; 16 a[i]*=10000; 17 M=max(a[i],M); 18 } 19 ll L=0;ll R=M; 20 ll ans=0; 21 while(L<=R){ 22 ll mid=(L+R)>>1;ll Min=0;int ok=0; 23 for(int i=1;i<=n;i++) 24 { 25 s[i]=s[i-1]+a[i]-mid; 26 if(i>=m) 27 { Min=min(Min,s[i-m]); 28 if(s[i]-Min>=0) 29 { 30 ok=1; 31 break; 32 } 33 } 34 } 35 if(ok) 36 { 37 ans=mid; 38 L=mid+1; 39 } 40 else R=mid-1; 41 } 42 cout <<ans/10<<endl; 43 return 0; 44 }