hdu2993 MAX Average Problem (斜率dp)
参考:http://www.cnblogs.com/kuangbin/archive/2012/08/27/2657878.html
//#pragma warning (disable: 4786) //#pragma comment (linker, "/STACK:16777216") //HEAD #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring> #include <queue> #include <string> #include <set> #include <stack> #include <map> #include <cmath> #include <vector> #include <iostream> #include <algorithm> using namespace std; //LOOP #define FE(i, a, b) for(int i = (a); i <= (b); ++i) #define FED(i, b, a) for(int i = (b); i>= (a); --i) #define REP(i, N) for(int i = 0; i < (N); ++i) #define CLR(A,value) memset(A,value,sizeof(A)) //INPUT #define RI(n) scanf("%d", &n) #define RII(n, m) scanf("%d%d", &n, &m) #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k) #define RS(s) scanf("%s", s) typedef long long LL; const int INF = 1000000007; const double eps = 1e-10; const int MAXN = 500010; int n, m; int sum[MAXN]; int q[MAXN]; double Up(int k, int j) { return sum[j] - sum[k]; } double Down(int k, int j) { return j - k; } double getDp(int i, int j) { return (sum[i] - sum[j]) * 1.0 / (i - j); } //o(n)法 //double solve() //{ // int be, ed; // be = 1; // ed = 0; // double ans = 0; // double tmp = 0; // //// q[++ed] = 0;/// // int j; // for (int i = m; i <= n; i++) // { // j = i - m; // while (be < ed && Up(q[ed - 1], q[ed]) * Down(q[ed], j) >= Up(q[ed], j) * Down(q[ed - 1], q[ed])) // ed--; // q[++ed] = j; // // while (be < ed && getDp(i, q[be]) <= getDp(i, q[be + 1])) // be++; // j = q[be]; // tmp = getDp(i, j); // ans = max(ans, tmp); // } // return ans; //} ///o(n*log(n))法,不单调是可用此法 bool check(int mid, int i) { // if (Up(q[mid], q[mid + 1]) * Down(q[mid + 1], i) >= Up(q[mid + 1], i) * Down(q[mid], q[mid + 1])) return 1; if (getDp(i, q[mid]) >= getDp(i, q[mid + 1])) return 1; return 0; } ///注意写法 int SB(int i, int l, int r)///[l, r] { int mid; while (l < r)///区间长度至少为2 { mid = (l + r) >> 1; if (check(mid, i)) r = mid;///!!!要是mid else l = mid + 1; } return l; } double fun() { int top = 1; int j; double ans = 0, tmp = 0; FE(i, m, n) { j = i - m; while (top > 1 && Up(q[top - 1], q[top]) * Down(q[top], j) >= Up(q[top], j) * Down(q[top - 1], q[top])) top--; q[++top] = j; j = q[SB(i, 1, top)]; tmp = getDp(i, j); ans = max(ans, tmp); } return ans; } int getInt() { int x = 0; char c = getchar(); while (c < '0' || c > '9') c = getchar(); while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x; } int main () { int x; while (~RII(n, m)) { sum[0] = 0; FE(i, 1, n) { x = getInt(); sum[i] = sum[i - 1] + x; } printf("%.2lf\n", fun()); } return 0; }