zoukankan      html  css  js  c++  java
  • hdu7048 /2021“MINIEYE杯”中国大学生算法设计超级联赛(7) 1005 Link with EQ

    https://acm.hdu.edu.cn/showproblem.php?pid=7048

    题意:

    一张可以做n个人的桌子,第一个人随便找一个位置坐,后面的人找一个距离有人的最短距离最大的位置坐。

    当一个人发现他必须要和某个人挨着坐时,这张桌子就满了。

    问当桌子坐满的时候,期望做了多少个人

    这是个线形的桌子,一直以为是圆桌。。。

    第一个人位置确定后,这个桌子能坐多少人也定好了

    设f[i]表示有连续的i+2个位置,两头都被坐了,还剩下中间i个空位,还能够坐的人数

    g[i]表示有连续的i+1个位置,一头被坐了,还剩下i个空位,还能够坐的人数

    h[i]表示有连续的i个位置能够坐的人数

    f[i]:

    若i是奇数,那么下一个人会坐最中间

    若i是偶数,那么下一个人会坐中间2个中的某一个。无论坐哪个,分成的左右两部分是一样的

    所以可以认为下一个人坐下之后,会把i分为 (i-1)/2 和 i-1-(i-1)/2 两部分

    所以 f[i]=f [(i-1)/2]+f[i-1-(i-1)/2]+1,i>=3

    当i<3时,f[i]=0

    g[i]:

    一头被坐了,下一个人必须坐距离它最远的位置,所以会坐到另一头

    所以g[i]=f[i-1]+1,i>=2

    当i<2时,g[i]=0

    h[i]:

    枚举第一个人坐在哪儿,设为x

    这样他把桌子分为左右两边,两边都是坐了一头

    h[i]=( ∑ g[x-1]+g[i-x]+1 ) / i ,x∈[1,i]

    h[i]= 2*(∑ g[x] ) / i ,x ∈[0,i-1]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 1000001
    
    const int mod=1e9+7;
    
    int f[N],g[N],sg[N],inv[N];
    
    int main()
    {
        for(int i=3;i<N;++i) f[i]=(f[i-1>>1]+f[i-1-(i-1>>1)]+1)%mod;
        for(int i=2;i<N;++i) g[i]=f[i-1]+1;
        for(int i=2;i<N;++i) sg[i]=(sg[i-1]+g[i])%mod;
        inv[1]=1;
        for(int i=2;i<N;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
        int T,n,ans;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            ans=(2ll*inv[n]*sg[n-1]%mod+1)%mod;
            printf("%d
    ",ans);
        }
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    splay
    开车旅行(2012day1T3)
    LCT入门
    最小瓶颈路
    poj 3041 Asteroids
    sql waitfor 延时执行
    [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server 不存在或访问被拒绝
    SQL Server中行列转换
    sql中 with rollup 、with cube、grouping 统计函数用法
    sql 分组后 组内排名
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15230773.html
Copyright © 2011-2022 走看看