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. ...
随机推荐
- 【BZOJ-4690】Never Wait For Weights 带权并查集
4690: Never Wait for Weights Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 88 Solved: 41[Submit][ ...
- Matlab中fsolve传递系数变量
比如AX= b,求解x,但是要找不同b下的x,100个b. fsolve(‘fun,[X0,b])这样是不行的,因为这样的话b也当成了变量,也会变. 两种方法 1.全局变量 global b;多个的话 ...
- JQuery冲突问题,以及含有jquery的框架与jquery冲突
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 【poj3709】 K-Anonymous Sequence
http://poj.org/problem?id=3709 (题目链接) 题意 给出一个n个数的序列,要求将其中一些数改为另一个比它小的数,改动的花费为两数的绝对值,完成改动后使得整个序列中出现过的 ...
- Android成长日记-Activity
① Activity是一个应用程序组件,提供用户与程序交互的界面 ② Android四大组件 ---Activity ---Service ---BroadcastReceiver ---Conten ...
- [SVN Mac自带SVN结合新浪SAE进行代码管理]
前一篇我转载了别人SVN的使用方法,前面的配置和服务器我不是很明白,自己尝试后发现我需要使用到的核心命令是下面一些. 新浪SAE提供了SVN代码管理仓库,只要进入相应应用,然后点击左侧代码管理,到最下 ...
- Linux命令点滴积累
1.批量删除当前目录及子目录中指定类型的文件: [root@localhost logs]# find ./ -name *.bak | xargs rm -rf [root@localhost lo ...
- 如何在Visual Studio 2013中使用Ribbon For WPF
1.首先需要 下载Ribbon For WPF.目前最新的版本是Microsoft Ribbon for WPF October 2010. 下载 链接: https://www.microsoft. ...
- oneM2M启动Release 3标准化,华为引领物联网技术布局
http://developer.huawei.com/cn/ict/news/cn/2016/06/onem2m [韩国,首尔,2016年6月] 国际权威的物联网组织oneM2M召开第23次技术全会 ...
- vs------连接MySQL
转载: http://jingyan.baidu.com/article/8ebacdf023953f49f65cd589.html
