您的位置:首页 > 其它

hdu 4923 Room and Moor 单调栈

2014-10-06 16:29 429 查看
首先可以忽略前面的0,和后面的1.剩下的就是由 a个1 b个0 组成的01串。由不等式可知y=(a+b)*x*x-a*x+a;x=a/(a+b)时函数值最小。

而值要求递增,所以把比当前值的段都加入当前段。最后模拟输出即可。#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define maxn 1100000
int save[maxn],n;
struct node
{
int len1,len0;
};
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
vector<node>a;
stack<node>sta;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&save[i]);
}
save[n+1]=1;
int st=1,ed=n;
while(save[st]==0)
{
st++;
}
while(save[ed]==1)
{
ed--;
}
// printf("%d %d\n",st,ed);
if(st==ed+1)
{
printf("0.000000\n");
continue;
}
node tmp;
tmp.len1=tmp.len0=0;
for(int i=st;i<=ed;i++)
{
if(save[i]==0)
{
tmp.len0++;
if(save[i+1]==1)
{
a.push_back(tmp);
tmp.len0=tmp.len1=0;
}
}
else
{
tmp.len1++;
}
}
/*
for(int i=0;i<a.size();i++)
{
printf("%d %d\n",a[i].len1,a[i].len0);
}
*/
sta.push(a[0]);
node now;
for(int i=1;i<a.size();i++)
{
while(!sta.empty())
{
now=sta.top();
if(a[i].len1*(now.len1+now.len0)>now.len1*(a[i].len1+a[i].len0))
{
sta.push(a[i]);
break;
}
else
{
sta.pop();
a[i].len1+=now.len1;
a[i].len0+=now.len0;
if(sta.empty())
{
sta.push(a[i]);
break;
}
}
}
}
double ans=0;
while(!sta.empty())
{
now=sta.top();
sta.pop();
double x=double(now.len1)/double(now.len1+now.len0);
ans+=double(now.len1)*(x-1)*(x-1)+double(now.len0)*x*x;
}
//ans=ans/double(n);
printf("%.6f\n",ans);

}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: