[POJ1018]Communication System(贪心)

来源:互联网 发布:php时间月份差 编辑:程序博客网 时间:2024/04/28 17:06

题目描述

传送门

题意:T组数据。每组数据给出一个n,输入n行,第i行mi个组合,每一个组合有B和P两个权。要求在这n行中每行都选出一个组合,最后使minBiPi最小。

题解

为什么是dp,明明就是个贪心。。。
枚举一个B,然后在所有大于B的里面每一行选一个,让P尽量小。
交上去了之后竟然跑了140+MS,非常不爽。于是各种砍常数优化循环什么的,其实把B排一下序然后动态维护一个Min时间是可以做到O(n2)的。最后砍成0MS好开心=▽=

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define N 105int T,n,m,cnt,tot;struct hp{int i;double b,p;}d[N*N];bool flag[N];double inf,Min[N],P,ans;void clear(){    n=m=0;cnt=tot=0;P=0;    memset(Min,127,sizeof(Min));inf=Min[0];    memset(flag,0,sizeof(flag));    ans=0;}int cmp(hp x,hp y){    return x.b>y.b;}int main(){    scanf("%d",&T);    while (T--)    {        clear();        scanf("%d",&n);        for (int i=1;i<=n;++i)        {            scanf("%d",&m);double x,y;            for (int j=1;j<=m;++j)            {                scanf("%lf%lf",&x,&y);hp now;                now.i=i,now.b=x,now.p=y;                d[++cnt]=now;            }        }        sort(d+1,d+cnt+1,cmp);        for (int i=1;i<=cnt;++i)        {            hp now=d[i];if (!flag[now.i]) flag[now.i]=true,tot++;            if (Min[now.i]==inf) Min[now.i]=now.p,P+=Min[now.i];            else if (now.p<Min[now.i]) P-=Min[now.i],P+=now.p,Min[now.i]=now.p;            if (tot!=n) continue;            ans=max(ans,now.b/P);        }        printf("%0.3lf\n",ans);    }}
0 0
原创粉丝点击