bzoj 3795: 魏总刷DP

Description

魏总,也就是DP魏又开始刷DP了。一共有n道题,第i道题魏总原本需要u[i]秒的时间。不过,为了表达对这些水题的藐视,魏总决定先睡k秒再开始刷题。魏总并不清楚自己会睡多久,只知道k是不超过m的正实数。并且魏总还忘了这节课有多长,只记得这节课的长度T(单位:秒)是在L到R之间。(魏总是从开始上课的时候开始睡的)睡醒后,魏总神奇地发现自己做每道题所需的时间变成了原来的k倍。不过DP魏就是DP魏,他可以同时做这n道DP,互不影响。

魏总本想虐场,但他很快发现自己低估这些题了。于是他决定将题分为HARD和EASY。对于每道HARD的题,他希望能最晚在下课后late[i]秒内完成,而对于EASY的题,他希望在下课前rest[i]秒之前完成。

求魏总达到目标的概率。

Input

第一行,一个整数n

第二行,三个实数m,L,R

第三行,n个整数,第i个为u[i]

就下来n行,每行一个字符串和一个整数,字符串为”HARD”或”EASY”,整数为对应的late[i]或rest[i]。

Output

一行,魏总达到目标的概率,保留4位小数。

将(k,T)看作平面上的点,约束条件为线性不等式,可以转为求半平面交的面积

#include<cstdio>
#include<algorithm>
const int N=100007;
int n,lp=0,p=0,as[N];
double xm,ym,S,S1=0,L,R;
char s[16];
struct pos{double x,y;}ps[N];
struct ln{
    double k,b;
    double x(double y){return (y-b)/k;}
    double y(double x){return k*x+b;}
    bool operator<(ln w)const{return k!=w.k?k<w.k:b>w.b;}
    bool in(pos w){return y(w.x)<=w.y;}
    pos operator&(ln w){
        double x=(w.b-b)/(k-w.k);
        return (pos){x,y(x)};
    }
}ls[N];
int main(){
    scanf("%d%lf%lf%lf",&n,&xm,&L,&R);
    ym=R-L;
    S=xm*ym;
    for(int i=1;i<=n;++i)scanf("%d",as+i);
    ls[lp++]=(ln){0,0};
    for(int i=1,b;i<=n;++i){
        scanf("%s%d",s,&b);
        if(s[0]==‘E‘)b*=-1;
        ls[lp++]=(ln){as[i]+1,-L-b};
    }
    std::sort(ls,ls+lp);
    for(int i=0;i<lp;++i){
        if(i&&ls[i].k==ls[i-1].k)continue;
        while(p>=2&&!ls[i].in(ls[p-2]&ls[p-1]))--p;
        ls[p++]=ls[i];
    }
    while(p>=2&&(ls[p-2]&ls[p-1]).x>xm)--p;
    int p0=0;
    while(p-p0>=2&&(ls[p0]&ls[p0+1]).x<0)++p0;
    ps[p0]=(pos){0,ls[p0].y(0)};
    if(ps[p0].y>=ym)return puts("0.0000"),0;
    for(int i=p0+1;i<p;++i)ps[i]=ls[i]&ls[i-1];
    ps[p]=(pos){xm,ls[p-1].y(xm)};
    if(ps[p].y>ym){
        while(p-p0>=2&&(ls[p-2]&ls[p-1]).y>ym)--p;
        ps[p]=(pos){ls[p-1].x(ym),ym};
    }
    for(int i=p0+1;i<=p;++i){
        S1+=(ps[i].x-ps[i-1].x)*(ym*2-ps[i].y-ps[i-1].y);
    }
    printf("%.4f",S1/S/2);
    return 0;
}
时间: 2024-10-07 18:47:20

bzoj 3795: 魏总刷DP的相关文章

BZOJ3795 : 魏总刷DP

对于HARD: 需要满足$k+u[i]\times k\leq T+late[i]$. 对于EASY: 需要满足$k+u[i]\times k\leq T-rest[i]$. 故对于HARD,设$a[i]=-late[i]$,对于EASY,设$a[i]=rest[i]$,并将所有题目的$u[i]$都$+1$. 那么需要满足$\max(u[i]\times k+a[i])\leq T$. 求出这些直线形成的下凸壳,分段积分即可. 时间复杂度$O(n\log n)$. #include<cstdio

BZOJ 2298 problem a(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2298 题意:一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) 思路:对于第i个人来说,区间[ai+1,n-bi]的人的分数相同.那么我们用sum[L][R]表示区间[L,R]中总人数.用f[i]表示前i个人中说真话的最大人数,那么f[j]=max(f[i-1]+sum[i][j]). map<pair<in

BZOJ 1076 奖励关(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1076 题意:n种宝物,每个宝物有两个属性: (1)价值:(2)该宝物的集合S,只有得到了集合S中的宝物时才能得到该宝物.每次从一个黑箱子中随机拿出一个宝物k,若k的集合S中的宝物都已经得 到,则k可要(也可不要),否则k不能要.每次拿到任意宝物概率相等.求随机拿K次的最大期望得分. 思路:从后向前,设f[i][j]表示到第i次拿完宝物,状态为j的最大价值.枚举i+1次拿的宝物k,若k的

BZOJ 1560 火星藏宝图(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1560 题意: 思路:f[i]表示到达i的最大收益.这样是 O(n^2)的.我们考虑,由于转移的条件,a^2+b^2<(a+b)^2,因此对于三个点A.B.C.若A能到B,B能到C,那么A也能到C, 但是不如经过B更好.因此,我们记录到达第j列最靠下的i即可.那么转移(x,y)时,用记录的前y列即可. struct node { int x,y,w; }; node a[N]; int

BZOJ 1801 中国象棋(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1801 题意:在n*m的棋盘上放若干炮使得不互相攻击.有多少种放法?可以放0个.1个....只要不互相攻击就行.. 思路:f[i][j][k]前i行j列有1个炮.k列有两个炮. int n,m; i64 f[N][N][N]; void up(i64 &x,i64 y) { x+=y; x%=mod; } i64 C(int x) { return x*(x-1)/2; } int ma

BZOJ 2331 地板(插头DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2331 题意:给出一个n*m的地面.有些是障碍.用L型的地板砖铺满.有多少种方案. 思路:用0表示没有插头,用1表示有插头且可以拐弯,用3表示有插头但是不能再拐弯了. 设有m列,轮廓线为[0,m].对于格子(i,j),设左插头x上插头y,那么转移有: (1)x=0,y=0:此时如图1-0,有三种转移,分别是1-1,1-2,1-3; (2)x!=0,y!=0:此时只有当x=y=1时可以转移

BZOJ 2306 幸福路径(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2306 题意:给出一个有向图,点有权值 a.初始时在点S.一个人在初始点能量为K=1,每走到下一个点能量值乘以p(p<1),到达一个点u 幸福度为 a[u]*K.求最大的幸福度. 思路:最后必然是走了一条链,或者是一个环(一直绕),或者是一条链加一个环.设f[i][j][k]表示从点j走了i步到达节点k的最大幸福度.那么f[i][j][j]就表示在绕环.那么在这个环上一直绕下去的期望为:

BZOJ 1925 地精部落(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1925 题意:求1到n个所有排列中有多少种满足高低交错. 思路:f[n][k]表示n个数,最后一个为k且最后两个递增,g[n][k]表示n个数最后一个数为k且最后两个递减.对于f[n][k],若我们将每个数x换为n+1-x,则就成了g[n][n+1-k],因此有:f[n][k]=g[n][n+1-k].那么可得: 由于对称性,我们计算出: 那么最后的答案就是2ans. i64 f[2][

BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )

考虑每批任务对后面任务都有贡献, dp(i) = min( dp(j) + F(i) * (T(i) - T(j) + S) ) (i < j <= N)  F, T均为后缀和. 与j有关的量只有t = dp(j) - F(i) * T(j) , 我们要最小化它. dp(j)->y, T(j)->x, 那么y = F(i) * x + t, 就是给一些点和一个斜率...然后最小化截距, 显然维护下凸包就可以了. 然后因为无比坑爹的出题人....时间可以为负数, 所以要用平衡树维护(