• hdu 6070 Dirt Ratio(分数规划)


    题目链接:hdu 6070 Dirt Ratio

    题意:

    给你n个数,让你找一段区间[l,r],使得[l,r]中不同的数的个数size/(r-l+1)最小。

    题解:

    Claris官方题解:

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     3 using namespace std;
     4 
     5 const int N=6e4+7;
     6 int t,n,a[N],lazy[N*4],la[N];
     7 double T[N*4],eps=1e-4;
     8 
     9 void build(double v,int l=1,int r=n,int rt=1)
    10 {
    11     lazy[rt]=0;
    12     if(l==r){T[rt]=l*v;return;}
    13     int mid=l+r>>1;
    14     build(v,l,mid,rt<<1),build(v,mid+1,r,rt<<1|1);
    15     T[rt]=min(T[rt<<1],T[rt<<1|1]);
    16 }
    17 
    18 void PD(int rt)
    19 {
    20     lazy[rt<<1]+=lazy[rt],lazy[rt<<1|1]+=lazy[rt];
    21     T[rt<<1]+=lazy[rt],T[rt<<1|1]+=lazy[rt],lazy[rt]=0;
    22 }
    23 
    24 void update(int L,int R,int v,int l=1,int r=n,int rt=1)
    25 {
    26     if(L<=l&&r<=R){lazy[rt]+=v,T[rt]+=v;return;}
    27     int mid=l+r>>1;
    28     if(lazy[rt])PD(rt);
    29     if(L<=mid)update(L,R,v,l,mid,rt<<1);
    30     if(R>mid)update(L,R,v,mid+1,r,rt<<1|1);
    31     T[rt]=min(T[rt<<1],T[rt<<1|1]);
    32 }
    33 
    34 double ask(int L,int R,int l=1,int r=n,int rt=1)
    35 {
    36     if(L<=l&&r<=R)return T[rt];
    37     int mid=l+r>>1;
    38     if(lazy[rt])PD(rt);double ans=1e12;
    39     if(L<=mid)ans=min(ans,ask(L,R,l,mid,rt<<1));
    40     if(R>mid)ans=min(ans,ask(L,R,mid+1,r,rt<<1|1));
    41     return ans;
    42 }
    43 
    44 int check(double mid)
    45 {
    46     build(mid),memset(la,0,sizeof(la));
    47     F(r,1,n)
    48     {
    49         update(la[a[r]]+1,r,1);
    50         la[a[r]]=r;
    51         if(ask(1,r)<=mid*(r+1))return 1;
    52     }
    53     return 0;
    54 }
    55 
    56 int main(){
    57     scanf("%d",&t);
    58     while(t--)
    59     {
    60         scanf("%d",&n);
    61         F(i,1,n)scanf("%d",a+i);
    62         double l=0,r=1,mid;
    63         F(ic,1,15)
    64         {
    65             if(r-l<eps)break;
    66             mid=(l+r)/2;
    67             if(check(mid))r=mid;else l=mid;
    68         }
    69         printf("%f
    ",mid);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    Centos7安装Docker
    [LeetCode] 651. 四键键盘 ☆☆☆(动态规划)
    一行代码就能解决的算法题
    博弈问题--石头游戏(动态规划)
    [LeetCode] 322. 零钱兑换 ☆☆☆(动态规划)
    java趣题
    [LeetCode] 516. 最长回文子序列 ☆☆☆(动态规划)
    [LeetCode] 337. 打家劫舍III ☆☆☆(动态规划)
    算法基础--贪心算法
    [LeetCode] 42. 接雨水 ☆☆☆☆☆(按列、动态规划、双指针)
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7291320.html
Copyright © 2020-2023  润新知