codeforces 578c//Weakness and Poorness// Codeforces Round #320 (Div. 1)
题意:一个数组arr,一个数字x,要使arr-x的最大子段最小,问该最小值。
三分x,复杂度logn,内层是最大子段的模板,只能用n复杂度的。因为是绝对值最大,正负各求一次,取大的。精度卡得不得了,要1e-12左右才能过。看着数据才调出精度的。
乱码:
//#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> #include <iomanip> using namespace std; const int SZ=1000010,INF=0x7FFFFFFF; const double EPS=8e-12; typedef long long lon; double arr[SZ],b[SZ],dp[SZ]; double max(double a[],int n) { double sum,maxsum; int i ; sum = maxsum = 0; for(i = 0;i<n;i++) { sum +=a[i]; if(sum>maxsum) maxsum = sum; else if(sum<0) sum = 0; } return maxsum; } double work(int n) { double res1=max(b,n); for(int i=0;i<n;++i)b[i]=-b[i]; double res2=max(b,n); return max(res1,res2); } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); //for(;scanf("%d",&n)!=EOF;) { int n; clock_t bg=clock(),end; cin>>n; for(int i=0;i<n;++i) { cin>>arr[i]; } double lo=-10010,hi=10010,res=0; for(;lo<hi&&fabs(lo-hi)>EPS;) { //end=clock(); //if(end-bg>1500)break; double mid1=lo+(hi-lo)/3; double mid2=lo+2*(hi-lo)/3; for(int i=0;i<n;++i) { b[i]=arr[i]-mid1; } double res1=work(n); for(int i=0;i<n;++i) { b[i]=arr[i]-mid2; } double res2=work(n); res=res1; //cout<<lo<<" "<<hi<<' '<<res<<endl; if(res1<res2)hi=mid2; else lo=mid1+1e-12; } cout<<fixed<<setprecision(10)<<res<<endl; } return 0; }
浙公网安备 33010602011771号