• Luogu5155 [USACO18DEC]Balance Beam


    题目链接:洛谷


    这道题看起来是个期望题,但是其实是一道计算几何(这种题太妙了)

    首先有一个很好的结论,在一个长度为$L$的数轴上,每次从$x$处出发,不停地走,有$frac{x}{L}$的概率从右端点掉下去,$frac{L-x}{L}$从左端点掉下去。

    这个证明的话,感性理解一下。

    令$l_x$表示从$x$处掉到左端点的概率,则$l_0=1,l_L=0$,且对于$xin (0,L)$,$l_x=frac{l_{x-1}+l_{x+1}}{2}$,所以$l_x$构成一个等差数列,所以得证。


    显然,我们肯定是不能一直走的,不然得分肯定是0,但是我们可以“掉进”一些权值比较高的点使得答案最优,我们称这些点为“停止点”。

    设从$x$处出发。

    如果$x$本身就是“停止点”,那么答案就是$f_x$。($f_x$为这个点的权值)

    否则$x$左右两侧的最近的“停止点”为$a,b$,这种策略的答案为$f_a*frac{b-x}{b-a}+f_b*frac{x-a}{b-a}$

    我们发现它就是$(a,f_a),(b,f_b)$两点连接的线段在$x$处的$y$值

    所以我们维护对$(x,f_x)(xin [0,n+1])$这$n+2$个点计算出上凸包,然后就是直接贪心计算了。

     1 #include<cstdio>
     2 #define Rint register int
     3 using namespace std;
     4 typedef long long LL;
     5 const int N = 100003;
     6 struct Point {
     7     LL x, y;
     8     inline Point operator - (const Point &o) const {return (Point){x - o.x, y - o.y};}
     9     inline LL operator * (const Point &o) const {return x * o.y - y * o.x;}
    10 } p[N];
    11 int n, top;
    12 LL a[N];
    13 inline void push(Point now){
    14     while(top > 1 && (now - p[top - 1]) * (p[top] - p[top - 1]) < 0) -- top;
    15     p[++ top] = now;
    16 }
    17 int main(){
    18     scanf("%d", &n);
    19     for(Rint i = 0;i <= n + 1;i ++){
    20         if(i && i <= n) scanf("%lld", a + i), a[i] *= 100000;
    21         push((Point){i, a[i]});
    22     }
    23     int now = 1;
    24     for(Rint i = 1;i <= n;i ++){
    25         while(p[now].x < i) ++ now;
    26         if(p[now].x == i) printf("%lld
    ", p[now].y);
    27         else {
    28             printf("%lld
    ", (LL) (1.0 * ((i - p[now - 1].x) * p[now].y + (p[now].x - i) * p[now - 1].y) / (p[now].x - p[now - 1].x)));
    29         }
    30     }
    31 }
    Luogu5155
  • 相关阅读:
    站立会议第二天
    站立会议第一天
    视频链接
    软件需求规格说明书模板(spec)
    个人NABCD
    团队项目及成员介绍
    会议视频
    软件需求规格说明书模板(Spec)
    团队计划backlog
    团队项目成员和题目
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/10719023.html
Copyright © 2020-2023  润新知