HDU 4923 Room and Moor(瞎搞题)

瞎搞题啊。找出1 1 0 0这种序列,然后存起来,这种情况下最好的选择是1的个数除以这段的总和。然后从前向后扫一遍,变扫边进行合并。每次合并,合并的是他的前驱。这样到最后从t-1找出的那条链就是最后满足条件的数的大小。

Room and Moor

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 307    Accepted Submission(s): 90

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

Source

2014 Multi-University Training Contest 6

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-9
///#define M 1000100
#define LL __int64
///#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 1000010;
int num[maxn];
int sum[maxn][2];
int pre[maxn];
double x[maxn];

int main()
{
    int T;
    cin >>T;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i = 0; i < n; i++) scanf("%d",&num[i]);
        int t = 0;
        int cnt1 = 0;
        int cnt2 = 0;
        if(!num[0]) cnt1 = 1;
        if(num[0]) cnt2 = 1;
        for(int i = 1; i < n; i++)
        {
            if(num[i] > num[i-1])
            {
                sum[t][0] = cnt1;
                sum[t++][1] = cnt2;
                cnt1 = cnt2 = 0;
                if(!num[i]) cnt1++;
                if(num[i]) cnt2++;
                continue;
            }
            if(!num[i]) cnt1++;
            if(num[i]) cnt2++;
        }
        sum[t][0] = cnt1;
        sum[t][1] = cnt2;
        t++;
        for(int i = 0 ; i < t; i++) x[i] = (1.0*sum[i][1]/((sum[i][0]+sum[i][1])*1.0));
        pre[0] = -1;
        for(int i = 1; i < t; i++)
        {
            if(x[i] < x[i-1])
            {
                sum[i][0] += sum[i-1][0];
                sum[i][1] += sum[i-1][1];
                x[i] = 1.0*sum[i][1]/(sum[i][1]+sum[i][0])*1.0;
                pre[i] = pre[i-1];
                int p = pre[i];
                while(p != -1)
                {
                    if(x[i] < x[p])
                    {
                        sum[i][0] += sum[p][0];
                        sum[i][1] += sum[p][1];
                        x[i] = 1.0*sum[i][1]/(sum[i][0]+sum[i][1])*1.0;
                        pre[i] = pre[p];
                        p = pre[p];
                        continue;
                    }
                    break;
                }
                continue;
            }
            pre[i] = i-1;
        }
        int p = pre[t-1];
        double ans =0;
        ans += sum[t-1][0]*pow(x[t-1], 2)+sum[t-1][1]*pow(x[t-1]-1, 2);
        while(p != -1)
        {
            ans += sum[p][0]*pow(x[p], 2)+sum[p][1]*pow(x[p]-1, 2);
            p = pre[p];
        }
        printf("%.6lf\n",ans);
    }
    return 0;
}

HDU 4923 Room and Moor(瞎搞题),布布扣,bubuko.com

时间: 2024-12-20 00:16:10

HDU 4923 Room and Moor(瞎搞题)的相关文章

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 4915 Parenthese sequence(瞎搞题)

从左向右扫一遍左括号的最大值,与最小值. 从右向左扫一遍右括号的最大值,与最小值. 比较最大值中的最小数与最小中的最大数看能否有交集,0个,1个或者多个. Parenthese sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 301    Accepted Submission(s): 129 Problem De

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

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(推理+栈维护)

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,利用一个栈去做维护,如果遇到一个位置递减了,那么就把

HDU 4923 Room and Moor【栈】【想法】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4923 题目大意:给你一串A = {A1, A2,..., AN}由{0,1}组成, 你要构造出一字符串 B = {B1, B2,... , BN}与A的长度相同. 求出这个最小值. 最开始见到这个题目先是想了想应该怎么做,比如先把A串处理一下. 1)把A前面的0去掉 2)把A后面的1去掉 3)将每部分的特值算出来. 举个栗子吧,字符串A将前的0去掉,后面的1去掉之后,字符串可以简化为N个 {1..

hdu 4923 Room and Moor(数学题)2014多校训练第6场

Room and Moor                                                                          Time 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

HDU 4923 Room and Moor 贪心+栈

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4923 题意:,Bi可以是小数. 思路:很机智的想法,对于连续M个1+N个0的一块来说,最优解一定是,Bi=M/(M+N),因为Bi是递增的(可以手推),所以如果出现在后面的一块中的Bi>前面一块的Bi,那么就不可能取到最优解,所以将两块合并一起处理,这样过程中就需要用栈来维护了. 代码: #include <iostream> #include <cstdio> #include &

hdu 4923 Room and Moor(线性表)

题目链接:hdu 4923 Room and Moor 题目大意:给定一个序列a,元素由0,1组成,求一个序列b,元素在0~1之间,并且保证递增.输出最小的∑(ai?bi)2, 解题思路:首先剔除为首的0,和末尾的1,然后将中间部分成若干段由连续1开头,连续0结尾的各个段落.对于每一段有一个最优的值x=aa+b(a为1的个数,b为0的个数),用栈维护各个段的x值,如果当前x值小于前面一个段的x值,那么就要将两个段合并,a=ai?1+ai,b=bi?1+bi. #include <cstdio>