cf578c Weakness and Poorness 三分
其实三分就是一个求单峰函数的最值的东西,用法比较统一。这个题就是观察发现不美好值是一个单峰函数,然后枚举t进行三分就行了。
题干:
给定一个长度为n的数组ai,求一个实数x,使得序列a1-x,a2-x,...,an-x的不美好程度最小。
不美好程度定义为,一个序列的所有连续子序列的糟糕程度的最大值。
糟糕程度定义为,一个序列的所有位置的和的绝对值。
输入 第一行n。
第二行n个数,表示ai。
输出 一个实数,精确到6位小数,表示最小不美好程度值。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int maxn = 2e5 + 5; const db eps = 1e-8; int arr[maxn]; db arr1[maxn]; int n; db calc(db arr[]) { db t = 0; db res = arr[0]; duke(i,0,n - 1) { t = arr[i] + t; res = max(res,t); if(t < eps) t = 0; } return res; } db solve(db t) { duke(i,0,n - 1) { arr1[i] = arr[i] - t; } db x1 = calc(arr1); duke(i,0,n - 1) arr1[i] = -arr1[i]; db x2 = calc(arr1); db x = max(fabs(x1),fabs(x2)); return x; } int main() { read(n); int maxnum = -10001,minnum = 10001; duke(i,0,n - 1) { read(arr[i]); maxnum = max(maxnum,arr[i]); minnum = min(minnum,arr[i]); } int dcnt = 100; db l = minnum ,r = maxnum; while(dcnt--) { db m1 = l + (r - l) / 3; db m2 = r - (r - l) / 3; db x1 = solve(m1); db x2 = solve(m2); if(x1 > x2) { l = m1; } else { r = m2; } } db res = solve(l); printf("%.8lf\n",res); return 0; }
只想找一个不会伤害我的人