hdu4923 Room and Moor
4923Room and Moor
Room and MoorTime Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Problem Description
PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that:
Input
The input consists of multiple test cases. The number of test cases T(T<=100) occurs in the first line of input.
For each test case: Output
Output the minimal f (A, B) when B is optimal and round it to 6 decimals.
Sample Input
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 Sample Output
1.428571
1.000000 0.000000 0.000000 Source
Recommend
hujie
|
题意:输入由1和0组成的A序列,求一个长度与A序列相同的、在实数[0,1]之间的不下降序列B,使得sum of (Ai-Bi)^2最小,输出这个最小的sum。
题解:
先观察一下,发现最左边的0和最右边的1可以忽视,因为我们可以把B左边这段当做0,B右边那段当1。解下来看剩下的。
假如有一段是1111.....00000,由x个1和y个0组成,则这一段最优的B是x/(x+y),也就是平均值,这可以通过样例看出。
而如果有两段这样的段,111...000 111....000,我们计算两段分别的平均值,若左段小于等于右段,则左段用左段的平均值,右段用右段的平均值是最优的;若左段大于右段,则不能各用各的平均值了,我们把这两段合作一段,用一起的平均值。
根据这个思想,我们把下降的段都合并了,得到平均值上升的若干段,各用各的平均值,哇,最优解!
合并时,从头到尾,相邻的组平均值比较。有可能会出现合并完这两个,新组平均值比再前一个组的平均值还小的情况,所以我们每次合并,都要和之前的比较一发,保证队列不下降。
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll __int64
#define usint unsigned int
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,x,n) for(int i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1.out","w",stdout) const int maxn=; struct pig {///分组,每个pig记录一组的和与长度
int sum,len;
pig(int s,int l) {
sum=s;
len=l;
}
pig() {}
long double ave() {///还能算平均值,怕不怕
return sum*1.0/len;
}
}; pig v[maxn];
int vl,vr;
int n;
bool a[maxn]; int main() {
int i,T,j;
int l,r;
int sum,len;
long double ans;
int flag;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(i=; i<n; i++)
scanf("%d",&a[i]);
l=;
r=n;
while(a[l]==&&l<n)l++;///去除左边的0
while(a[r-]==&&r>=)r--;///去除右边的1
sum=0.0;
flag=;
len=;
vl=;
vr=;
for(i=l; i<r; i++) {///将剩下的分成若干组不上升序列,记录各组的和与长度
//cout<<i<<'.'<<sum<<'/'<<len<<endl;
if(a[i]==) {
if(flag==)
sum++,len++;
else if(flag==) {
v[vr++]=(pig(sum,len));
sum=a[i];
len=;
flag=;
}
} else if(a[i]==) {
len++;
if(flag==)
flag=;
}
}
if(len>) v[vr++]=pig(sum,len);///把最后剩下的一组也加入
for(i=vl+; i<vr; i++) {
if(v[i-].ave()>v[i].ave()) {///若相邻两组平均值呈下降,则合并为一组
v[i].sum+=v[i-].sum;
v[i].len+=v[i-].len;
v[i-].sum=;
v[i-].len=;
for(j=i-; j>=; j--)
if(v[j].len>) {
if(v[j].ave()>v[i].ave()) {///有可能合并完后小于更之前的平均值,若发生这种事,则把之前的也合并进来
v[i].sum+=v[j].sum;
v[i].len+=v[j].len;
v[j].sum=;
v[j].len=;
}
else break;
}
}
}
while(v[vl].len== && vl<vr) vl++;///去除开头的空组
// printf("vl=%d,vr=%d:",vl,vr);
// for(i=vl;i<vr;i++)
// printf("%.6f,%d ",v[i].sum,v[i].len);
// puts("");
ans=0.0;
for(i=vl; i<vr; i++) {
if(v[i].len!=) {///若为非空组,则统计len*(1-ave)^2+(len-sum)*ave^2
//cout<<v[i].sum<<','<<v[i].len<<','<<(double)v[i].ave()<<endl;
//cout<<(long double)ave<<','<<(long double)ave2<<','<<(long double)(len-v[i].sum)<<endl;
if(v[i].len>) ans+=( v[i].ave() * v[i].ave() ) * (v[i].len-v[i].sum) + (1.0-v[i].ave())*(1.0-v[i].ave()) * v[i].sum;
//cout<<ans<<endl;
}
}
printf("%.6f\n",(double)ans);
}
return ;
}
hdu4923 Room and Moor的更多相关文章
- 【HDU】4923 Room and Moor(2014多校第六场1003)
Room and Moor Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- HDU 4923 Room and Moor (多校第六场C题) 单调栈
Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. ...
- HDOJ 4923 Room and Moor
用一个栈维护b的值,每次把一个数放到栈顶. 看栈首的值是不是大于这个数,假设大于的话将栈顶2个元素合并.b的值就是这两个栈顶元素的平均值. .. Room and Moor Time Limit: 1 ...
- HDU 4923 Room and Moor(推理+栈维护)
HDU 4924 Room and Moor 题目链接 题意:给定一个01组成的a序列.要求一个b序列,b序列每一个数值为[0, 1]之间的数,而且b序列为非递减序列,要求∑(ai−bi)2最小,求这 ...
- hdu 4923 Room and Moor [ 找规律 + 单调栈 ]
传送门 Room and Moor Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...
- HDU 4923 Room and Moor(瞎搞题)
瞎搞题啊.找出1 1 0 0这样的序列,然后存起来,这样的情况下最好的选择是1的个数除以这段的总和. 然后从前向后扫一遍.变扫边进行合并.每次合并.合并的是他的前驱.这样到最后从t-1找出的那条链就是 ...
- HDU 4923 Room and Moor (单调栈)
题意: 给你一个A数列,让你求一个单调递增的B数列(0<=bi<=1),使得sum{(ai-bi)^2}最小. 思路: 很明显,如果A = 0...01...1,那么bi=ai即可. 可以 ...
- 写一个TODO App学习Flutter本地存储工具Moor
写一个TODO App学习Flutter本地存储工具Moor Flutter的数据库存储, 官方文档: https://flutter.dev/docs/cookbook/persistence/sq ...
- HDU 4923 Room and Moor
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4923 解题报告:给出一个长度为n的只包含0和1的序列,是否存在一个序列Bi满足一下条件: 1. ...
随机推荐
- 【caffe】基本数据结构blob
@tags: caffe blob blob是caffe中的基本数据结构,简单理解就是一个"4维数组".但是,这个4维数组有什么意义? BTW,TensorFlow这款google ...
- 【BZOJ-2839】集合计数 容斥原理 + 线性推逆元 + 排列组合
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 229 Solved: 120[Submit][Status][Discuss] ...
- linux永久更改eth0的ip地址
linux中永久修改ip和子网掩码,可以用命令也可以直接到文件里修改.这里推荐直接到文件中修改.1.进入网卡配置文件 vi /etc/sysconfig/network-scripts/ifcfg-e ...
- vs2010 mvc3安装时报错
今天在研究以往的商城项目时,由于前台使用的是MVC3,在没有安装MVC3的插件时,提示未能加载项目,但是在安装过程中,又提示安装失败: 决定折腾一下->居然找到一篇以前别人写的神作,特此记录一下 ...
- waf2控件名
1,查询表格(queryGrid),编辑表格(editGrid) wafGrid 2,快速F7 wafPromptQuick 3,表格F7 wafPromptGrid 4,自定义F7 wafPromp ...
- java-HashMap方法讲解
前言:Java8之后新增挺多新东西,在网上找了些相关资料,关于HashMap在自己被血虐之后痛定思痛决定整理一下相关知识方便自己看.图和有些内容参考的这个文章:http://www.importnew ...
- Jboss7.1 加入realm auth认证 bootsfaces 美化的登录页面
jboss-as-7.1.1.Final\standalone\configuration: 1, standalone.xml中 <security-domains>标签里面添加: &l ...
- 机器学习笔记--KNN算法2-实战部分
本文申明:本系列的所有实验数据都是来自[美]Peter Harrington 写的<Machine Learning in Action>这本书,侵删. 一案例导入:玛利亚小姐最近寂寞了, ...
- Blast本地化
转载]Blast本地化:使用Blastall进行数据库比对 (2012-02-13 21:25:31) 用blastall进行序列比对 blastall是最常用的blast程序之一,其功能非常强大 ...
- jquery 获取json文件数据,显示到jsp页面上, 或者html页面上
[{"name":"中国工商银行","code":102},{"name":"中国农业银行",&qu ...