
4 9 1 1 1 1 1 0 0 1 1 9 1 1 0 0 1 1 1 1 1 4 0 0 1 1 4 0 1 1 1
1.428571 1.000000 0.000000 0.000000
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
int const MAX = 1e5 + 5;
struct DIVIDE
{
int c0, c1;
double val;
}d[MAX];
int a[MAX];
stack <DIVIDE> stk;
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
double ans = 0;
memset(a, 0, sizeof(a));
scanf("%d", &n);
int st = 1, ed = n;
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
while(ed >= 1 && a[ed] == 1)
ed --;
while(st <= n && a[st] == 0)
st ++;
int cnt = 0;
for(int i = st; i <= ed; i++)
{
if(a[i] == 1)
{
if(a[i - 1] == 0)
{
cnt ++;
d[cnt].c0 = d[cnt].c1 = 0;
}
d[cnt].c1 ++;
}
else
d[cnt].c0 ++;
}
for(int i = 1; i <= cnt; i++)
d[i].val = (d[i].c1 * 1.0) / ((d[i].c1 + d[i].c0) * 1.0);
for(int i = 1; i <= cnt; i++)
{
if(stk.empty() || d[i].val >= stk.top().val)
stk.push(d[i]);
else
{
while(!stk.empty() && d[i].val < stk.top().val)
{
d[i].c0 += stk.top().c0;
d[i].c1 += stk.top().c1;
d[i].val = (d[i].c1 * 1.0) / ((d[i].c1 + d[i].c0) * 1.0);
stk.pop();
}
i --;
}
}
while(!stk.empty())
{
int c1 = stk.top().c1;
int c0 = stk.top().c0;
double val = stk.top().val;
ans += c1 * (1.0 - val) * (1.0 - val) + c0 * val * val;
stk.pop();
}
printf("%.6f\n", ans);
}
}HDU 4923 Room and Moor (数学+单调栈)
原文:http://blog.csdn.net/tc_to_top/article/details/44536675