hdu4923(想法题)

题意:给一个有0 和 1 组成的序列A,求一个B序列,满足三个条件,的最优值
这是一道想法题。
预处理:
1、 将最前面的0去掉,将最后面的1去掉;
2、 将串分成若干个连续的1+连续的0,比如1100111000,分成1100, 111000 ,记为a1b1,a2b2.....
3、 x1 = a1/(a1+b1),x2 = a2/(a2+b2)......如果rate是递增的,那么就简单了,但是这里并不一定是递增的;

4、 

如果看懂了上图的话,那么这题就可以解决了,这里还需要一个栈来模拟这个过程


代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define N 100005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
int a[N];
struct node
{
    int num1,num0;
    double rate;
}b[N];
stack<node> q;
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int i;
        for(i = 0; i < n; i++)
            scanf("%d",&a[i]);
        i = 0;
        while(a[i] == 0) i++;
        while(a[n-1] == 1) n--;
        a[n] = -1;
        int temp = 0,flag = 0,tot = 0;
        for(; i < n; i++)
        {
            temp++;
            if(a[i] != a[i+1]){
                if(flag%2 == 0) b[tot].num1 = temp;
                else  b[tot++].num0 = temp;
                temp = 0;
                flag++;
            }
        }
        while(!q.empty())  q.pop();
        for(i = 0; i < tot; i++)
        {
                double rat = 1.0*b[i].num1/(b[i].num1+b[i].num0);
                node tmp;
                tmp.rate = rat; tmp.num1 = b[i].num1; tmp.num0 = b[i].num0;
                while(1)
                {

                    if(q.size() == 0 || q.top().rate < tmp.rate)
                    {
                        q.push(tmp);
                        break;
                    }
                    node tmp1 = q.top();
                    q.pop();
                    tmp.num1 += tmp1.num1;
                    tmp.num0 += tmp1.num0;
                    tmp.rate = 1.0*tmp.num1/(tmp.num1+tmp.num0);
                }
        }
        double ans = 0;
        while(!q.empty())
        {
            node tmp = q.top();
            q.pop();
            ans = ans + 1.0*tmp.num1*(1.0 - tmp.rate)*(1.0 - tmp.rate) + 1.0*tmp.num0*tmp.rate*tmp.rate;
        }
        printf("%.6lf\n",ans);

    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值