题意:给你一个正整数序列,让你删去一段区间内的数[l,r] $1<lle r <n$
使得剩余的数平均值最小$nle 10^5$
1、不难想到暴力,用前缀和优化$O(n^2)$
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> #include<cmath> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } double ans=0x7fffffff; int a[105050]; int s[105050]; int n; signed main() { n=read(); for(int i=1;i<=n;i++) { a[i]=read(); s[i]=s[i-1]+a[i]; } for(int i=2;i<n;i++) for(int j=i;j<n;j++) { int tot=s[n]-(s[j]-s[i-1]); ans=min(ans,(double)(tot)/(double)(n-(j-i+1))); } printf("%.3lf",ans); olinr ~~(0^_^0)+love_nmr; }
2、正解:二分答案!
怎么二分呢(我没看出来)
于是深(da)入(kai)思(ti)考(jie)
发现对于暴力,可以变个形
$frac{sum[n]-(sum[j]-sum[i])}{n-(j-i)}ge x(二分一个答案x)$
$sum[n]-sum[j]+sum[i]ge nx-jx+ix$
$(sum[n]-nx)+(sum[i]-ix)-(sum[j]-jx)ge 0$
卧槽,好神奇
那么,我们令$a=sum[i]-ix$
直接O(n)看看答案是否成立,
因此总复杂度$O(nlogn)$
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> #include<cmath> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } int s[105050]; int n; double a[105050]; double minn; double eps=1e-4; inline bool ok(double mid) { for(int i=1;i<=n;i++) a[i]=(double)s[i]-i*mid; minn=a[1]; for(int i=2;i<n;i++) { if(a[n]-(a[i]-minn)<=0) return false; minn=min(minn,a[i]); } return true; } signed main() { n=read(); for(int i=1;i<=n;i++) s[i]=s[i-1]+read(); double l=0; double r=(double)(s[n]-(s[n-1]-s[1]))/(double)(2.0); while(r-l>=eps) { double mid=(double)(l+r)/(double)2.0; if(ok(mid)) l=mid; else r=mid; } printf("%.3lf",l); olinr ~~(0^_^0)+love_nmr; }