Hdu 4923(单调栈)

题目链接

Room and Moor

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 842    Accepted Submission(s): 250

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:
The first line contains a single integer N (1<=N<=100000), which denotes the length of A and B.
The second line consists of N integers, where the ith denotes Ai.

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

 Accepted Code:

 1 /*************************************************************************
 2     > File Name: 4923.cpp
 3     > Author: Stomach_ache
 4     > Mail: [email protected]
 5     > Created Time: 2014年08月08日 星期五 22时27分38秒
 6     > Propose:
 7  ************************************************************************/
 8
 9 #include <cmath>
10 #include <string>
11 #include <cstdio>
12 #include <fstream>
13 #include <cstring>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17
18 const double eps = 1e-12;
19 const int maxn = 100002;
20 int n;
21 int a[maxn], st[maxn];
22
23 struct node {
24     double x; //区间均值
25     int l, r, one; //区间范围及1的个数
26 }A[maxn];
27
28 // unite i to j
29 void unite(int i, int j) {
30       A[j].l = A[i].l;
31     A[j].x = A[j].one + A[i].one + 0.0;
32     A[j].x /= A[j].r - A[j].l + 1;
33     A[j].one = A[i].one + A[j].one;
34 }
35
36 double solve() {
37       int len = 1;
38     for (int i = 1; i <= n; i++) {
39           A[len].x = a[i] + 0.0;
40         A[len].l = i;
41         i++;
42         while (i <= n && a[i] == a[i-1]) i++;
43         A[len].r = i - 1;
44         i--;
45         if (a[i]) A[len].one = A[len].r - A[len].l + 1;
46         else A[len].one = 0;
47         len++;
48     }
49     int top = 0;
50     for (int i = 1; i < len; i++) {
51           while (top && A[i].x < A[st[top-1]].x) {
52               unite(st[top-1], i);
53             top--;
54         }
55         st[top++] = i;
56     }
57     double ans = 0.0;
58     for (int i = 0; i < top; i++) {
59           for (int j = A[st[i]].l; j <= A[st[i]].r; j++) {
60               ans += (a[j] - A[st[i]].x) * (a[j] - A[st[i]].x);
61         }
62     }
63     return ans + eps;
64 }
65
66 int main(void) {
67       int t;
68     scanf("%d", &t);
69     while (t--) {
70           scanf("%d", &n);
71         for (int i = 1; i <= n; i++) scanf("%d", a + i);
72         printf("%.6f\n", solve());
73     }
74     return 0;
75 }

Hdu 4923(单调栈)

时间: 2024-11-05 18:31:07

Hdu 4923(单调栈)的相关文章

hdu 1506 单调栈问题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题目的意思其实就是要找到一个尽可能大的矩形来完全覆盖这个矩形下的所有柱子,只能覆盖柱子,不能留空. 我们求得的面积其实就是Max{s=(right[i] - left[i] + 1)*height[i];(i>=1&&i<=n)} 每一个柱子都要尽可能向左向右延伸,使得获得最大的面积. 此时我就要用到单调栈 单调栈就是栈内元素单调递增或者单调递减的栈,单调栈只能在栈顶操作.

HDU 5033---Building(单调栈)

题目链接 Problem Description Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers loc

hdu 5875(单调栈)

Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1866    Accepted Submission(s): 674 Problem Description The shorter, the simpler. With this problem, you should be convinced of this tr

hdu 5033 单调栈 ****

看出来是单调栈维护斜率,但是不会写,2333,原来是和询问放在一起的 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <cmath> 7 typedef __int64 ll; 8 using namespace std; 9 10 const doub

HDU 5033 (单调栈维护凸包) Building

题意: 一个人在x轴上,他的左右两侧都有高楼,给出楼的横坐标Xi和高度Hi还有人的位置pos,求人所能看到的天空的最大角度. 分析: 将建筑物和人的位置从左到右排序,对于每个位置利用栈求一次人左边建筑物的凸包,找到一个最小的角度,然后对称一下,再找一个右边的建筑物的最小角度,两个角度加起来就是答案. 将人左边的建筑物从左到右扫描,下面两种情况会出栈: 栈顶元素楼高小于等于当前扫描到的楼高,因此这是一个单调的栈 栈顶两个楼顶所在直线的斜率 小于 栈顶的楼顶和当前楼顶所在直线的斜率(这里的斜率指的是

hdu 3410 单调栈

http://acm.hdu.edu.cn/showproblem.php?pid=3410 Passing the Message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 827    Accepted Submission(s): 546 Problem Description What a sunny day! Let's

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. 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 inp

hdu 4923 Room and Moor (单调栈+思维)

题意: 给一个0和1组成的序列a,要构造一个同样长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得  sum((ai-bi)^2)最小. 算法: 首先a序列开始的连续0和末尾的连续1是可以不考虑的.因为只要b序列对应开头为0. 末尾为1,既不影响单调性又能使对应的(ai-bi)^2=0. 然后, 先找111100.11100.10这样以1开始以0结束的序列块.每一块对应的b值相等且均为 这一块的平均值,即1的个数/0和1的总个数. 但是要满足b的单调性,则我们用栈来维护,如果后面一

HDU 4923 Room and Moor(推理+栈维护)

HDU 4924 Room and Moor 题目链接 题意:给定一个01组成的a序列,要求一个b序列,b序列每个数值为[0, 1]之间的数,并且b序列为非递减序列,要求∑(ai?bi)2最小,求这个最小值 思路:推理,很容易看出,开头一段的0和末尾一段的1等于没有,然后中间每段类似111000这样1在前,0在后的序列,都可以列出一个公式,很容易推出选择的x为共同的一个值,为1的个数/(1的个数+0的个数)a,那么问题就变成要维护一个递增的x,利用一个栈去做维护,如果遇到一个位置递减了,那么就把