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

题意:不多说了。

sl: 其实就是一个贪心的思想。

网上讲解很多。比赛时没搞出来。。。呵呵了。

1 // by caonima
 2 // hehe
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <stack>
 6 #include <queue>
 7 #include <vector>
 8 #include <algorithm>
 9 using namespace std;
10 const int MAX = 1e6+10;
11 struct node {
12     int one,zero;
13     double val;
14 }v[MAX];
15 stack<node> ans;
16 int a[MAX];
17 void init() {
18     while(!ans.empty()) ans.pop();
19 }
20 int main() {
21     int cas,n;
22     scanf("%d",&cas);
23     while(cas--) {
24         scanf("%d",&n);
25         for(int i=1;i<=n;i++) {
26             scanf("%d",&a[i]);
27         }
28         a[n+1]=1;
29         int L=1,R=n;
30         while(a[L]==0) L++;
31         while(a[R]==1) R--;
32         if(L>=R) printf("0.000000\n");
33         else {
34             int id=0;
35             for(int i=L;i<=R;) {
36                 int cnt0=0,cnt1=0;
37                 while(a[i]==1) {
38                     cnt1++; i++;
39                 }
40                 while(a[i]==0) {
41                     cnt0++; i++;
42                 }
43                 v[id].one=cnt1; v[id].zero=cnt0;
44                 v[id++].val=(double) cnt1/(double)(cnt0+cnt1);
45             }
46             init();
47             for(int i=0;i<id;i++) {
48 
49                 if(ans.empty()) ans.push(v[i]);
50                 else {
51                     node vn=ans.top();
52                     if(vn.val<=v[i].val) ans.push(v[i]);
53                     else {
54                         node t=v[i];
55                         while(true) {
56                             node vx=ans.top();
57                             if(vx.val>t.val) {
58                                 t.one+=vx.one; t.zero+=vx.zero;
59                                 t.val=(double) t.one/(double)(t.one+t.zero);
60                                 ans.pop();
61                             }
62                             else {
63                                 ans.push(t);
64                                 break;
65                             }
66                             if(ans.empty()) {
67                                 ans.push(t);
68                                 break;
69                             }
70                         }
71                     }
72                 }
73             }
74             double res=0;
75             while(!ans.empty()) {
76                 node vn=ans.top();
77                 ans.pop();
78                 res+=vn.val*vn.val*vn.zero+(1-vn.val)*(1-vn.val)*vn.one;
79             }
80             printf("%.6lf\n",res);
81         }
82 
83     }

84 }

HDU 4923 (贪心+证明),布布扣,bubuko.com

时间: 2024-12-09 20:59:40

HDU 4923 (贪心+证明)的相关文章

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 &

2014多校联合六(HDU 4923 HDU 4925 HDU 4927 HDU 4930)

HDU 4923 Room and Moor 题意:给出A序列  求满足题目所写的B序列  使得方差最小 思路:可以想到最后的结果中  B序列的值一定是一段一段的  那么我们可以类似贪心去搞  对于一段序列我们可以求出什么样的b值使得方差最小  即序列中1的个数除以序列长度  又因为B是单调的  可以用一个单调栈去模拟  复杂度远远小于n^2  不要被吓怕- 代码: #include<cstdio> #include<cstring> #include<algorithm&g

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

瞎搞题啊.找出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 Su

hdu 4105 贪心思想

淋漓尽致的贪心思想 波谷一定是一位数,波峰一位数不够大的时候添加到两位数就一定够大了的. 当在寻找波谷碰到零了就自然当成波谷. 当在寻找波峰时碰到零时,将前面的波谷加到前一个波峰上,让当前的零做波谷,使得波谷的值尽量小,这就是本题最关键的贪心思想,一直想不到. 代码中:a表示前一个值,b表示当前考虑的值,tag为偶数时表示正在寻找波谷,奇数时在寻找波峰. #include<iostream> #include<cstdio> #include<cstring> #inc

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 2037 贪心

今年暑假不AC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 27361    Accepted Submission(s): 14439 Problem Description "今年暑假不AC?" "是的." "那你干什么呢?" "看世界杯呀,笨蛋!" &quo

HDU 4932 贪心

Miaomiao's Geometry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 191    Accepted Submission(s): 38 Problem Description There are N point on X-axis . Miaomiao would like to cover them ALL by