• bzoj 1701 [Usaco2007 Jan]Cow School牛学校


    [Usaco2007 Jan]Cow School牛学校

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 175  Solved: 83
    [Submit][Status][Discuss]

    Description

    Bessy 正在上学并且分数还不错. 她考了N (一个数据中1 <= N <= 50,000, 其余数据 1 <= N <= 50,00) 次试,每次考试得分为T_i, 满分为P_i(0 <= T_i <= P_i < 40,000; 0 < P_i). 在计算总分时,她的老师先将把分数(P_i/T_i)最高的D个试卷去掉,然后将其余P_i 的和除以其余T_i的和作为Bessy的分数. Bessy精通数学,所以很快发觉这并没有想象中那么好. Bessy想告诉她的老师所有附和以下条件的D: 如果令一组(D个)分数去掉,她的分数回比老师算出来的更高. Bessy 很惊讶地发现她没有两次考试得分百分点是一样的.

    Input

    *第一行: N

    *第2..N+1行: 第i行里有 T_i 和 P_i.

    Output

    * 第一行: K, 符合条件的D的个数.

    *第2..K+1行: 按递增顺序,每行一个符合条件的D.

    Sample Input

    5
    1 2
    5 9
    3 8
    4 10
    1 3

    输入解释:

    Bessy 考了5门试, 分数分别为1/2, 5/9, 3/8, 4/10, 1/3.

    Sample Output

    2
    1
    2
     
    题解:

    枚举剩下的分数个数kk,设最高的kk个分数和的分子分母分别为UU和DD。

    那么在选了的里面找到A=min(Dt[x]Up[x])A=min(Dt[x]−Up[x]),没选的里面找到B=max(Dt[x]Up[x])B=max(Dt[x]−Up[x])。

    如果A<BA<B,则可以更大。

    对于A,BA,B的计算,可以利用决策单调性分治求解。

    时间复杂度O(nlogn)O(nlog⁡n)。

    十分优秀的思想。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 
     7 #define ll long long
     8 #define ls tr[p].l
     9 #define rs tr[p].r
    10 #define N 100007
    11 using namespace std;
    12 const ll inf=2000000000000010;
    13 inline ll read()
    14 {
    15     ll x=0,f=1;char ch=getchar();
    16     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 
    21 int n,ans,q[N];
    22 ll f[N],g[N];
    23 struct Node
    24 {
    25     int t,p;
    26 }a[N],b[N];
    27 
    28 inline bool cmp(Node a,Node b)
    29 {
    30     return a.t*b.p>b.t*a.p;
    31 }
    32 void getf(int l,int r,int dl,int dr)
    33 {
    34     int m=(l+r)>>1,dm;
    35     f[m]=inf;
    36     for(int i=dl;i<=m&&i<=dr;i++)
    37     {
    38         ll t=1LL*a[i].t*b[m].p-1LL*a[i].p*b[m].t;
    39         if(t<f[m])f[m]=t,dm=i;
    40       }
    41     if(l<m)getf(l,m-1,dl,dm);
    42     if(r>m)getf(m+1,r,dm,dr);
    43 }
    44 void getg(int l,int r,int dl,int dr)
    45 {
    46     int m=(l+r)>>1,dm;
    47     g[m]=-inf;
    48       for(int i=dr;i>m&&i>=dl;i--)
    49     {    
    50         ll t=1LL*a[i].t*b[m].p-1LL*a[i].p*b[m].t;
    51         if(t>g[m])g[m]=t,dm=i;
    52       }
    53       if(l<m)getg(l,m-1,dl,dm);
    54       if(r>m)getg(m+1,r,dm,dr);
    55 }
    56 int main()
    57 {
    58     scanf("%d",&n);
    59       for(int i=1;i<=n;i++)
    60         scanf("%d%d",&a[i].t,&a[i].p);
    61       sort(a+1,a+n+1,cmp);
    62       for(int i=1;i<=n;i++)
    63           b[i].t=b[i-1].t+a[i].t,b[i].p=b[i-1].p+a[i].p;
    64       getf(1,n-1,1,n),getg(1,n-1,1,n);
    65       for(int i=1;i<n;i++)
    66           if(f[i]<g[i]) q[++ans]=n-i;
    67     printf("%d
    ",ans);
    68     for(int i=ans;i;i--)
    69         printf("%d
    ",q[i]);
    70 }
  • 相关阅读:
    3月21日软件工程概论课堂测验
    四则运算2
    构建之法阅读笔记01
    软件工程学习进度条02-06
    软件工程个人作业01
    简牍《构建之法》
    2月29日课后作业
    读《大道至简》第七八章有感
    个人冲刺——第十天
    人月神话阅读笔记02
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8065972.html
Copyright © 2020-2023  润新知