zoukankan      html  css  js  c++  java
  • 2017CodeM初赛B场

    A、合并字符串价值(loj6174)

    分析:

    普通暴力:枚举两个分界线,那么ans=Σmin(Al(c)+Bl(c),Ar(c)+Br(c)),这样是O(n^2),会TLE

    考虑枚举a的分界线,b的答案根据之前的答案进行转移

    显然,4个字母A G C T可以单独考虑

    假设当前a分界线下,a的左部分该字母有p个,右部分该字母有q个(p,q显然为已知数)

    我们来考察b分界线,假设b分界线左边有k个该字母,右边有t-k个该字母(k为未知数,t为已知数,t是b字符串该类字母的总数)

    那么现在该分界线对答案的贡献就是min(p+k,q+t-k)

    遇见min就分类讨论:

      k<=(q-p+t)/2时,贡献是p+k

      k>(q-p+t)/2时,贡献是q+t-k

    分析完了状态,我们去考虑快速转移答案

    假设p,q,k,t-k情况下的答案我们已经知道了,现在我们分析a分界线向右移动的情况

    这个时候,p=p+1,q=q-1

      k<=(q-p+t)/2-1时,贡献是p-1+k

      k>(q-p+t)/2-1时,贡献是q+1+t-k

    这个很明显,某一段区间集体-1,某一段区间集体+1,某一段区间集体更改成一个值,用线段树去维护

    具体地:设m=(q-p+t)/2

    首先k<m这些,贡献全部-1;k>m这些,贡献全部+1

    k=m这些,贡献全部变成q-1+t-m

    (这里我本想偷懒一下,用区间加减来代替覆盖,就是求上一次该位置的贡献,是p+m,但是这有细节……等下再提)

    所以直接线段树维护就行了,询问就是max

    时间复杂度O(nlogn)

    细节:

    1、注意线段树下标从0开始,表示b数组取左边0个的最优值

    2、注意初始值的构造

    3、注意m=0,m=负数的时候,k的取值不一定就是m了,比如k<-3,实际上就是k<0,不需要修改,k>-3,实际上是k>=0,全部都要修改

    4、注意m正负还不够,还要注意m<=0的时候,某位置上一次的贡献不一定是p+m了,因为会出现两个区间重叠,有个好办法就是min(p+m,q+t-m)

    B、黑白树(loj6175)

    分析:

    贪心,按照拓扑结构,从叶子节点向上涂色,遇见一个未染色节点的时候,那么就在这个节点的子树中,选择一个能上升到离根节点最近的点,让这个点涂色。

    具体实现的时候树形dp就可以了

    dp[u]表示以u为根的子树全部涂完,能额外上升到最小的深度

    dp[u]=min(dp[u],dp[v],dep[u]-a[u]+1)

    f[u]表示实际上以u为根的子树,把颜色涂到了哪个深度

    f[u]=min(f[u],f[v])

    如果当一个点u,所有的子树都做完了

    发现f[u]==inf,就说明u不能涂到,这时候就要启用一个子节点涂色了

    很明显这时候我们用dp[u]保存的那个最优值

    也就是f[u]=dp[u],并且因为多启用了一个子节点,所以ans++

    C、模(loj6176)

    占坑

    D、送外卖(loj6177)

    分析:

    n和q都十分小,所以自然考虑状态压缩dp

    那么很容易列方程dp[S][now]表示现在q个订单状态为S,我现在在now点,花费的最少时间

    仔细想想订单有3个状态:未领、已领、已送达

    所以S要是三进制

    一重循环枚举S,一重循环枚举now,一重循环枚举一个订单作为转移,时间复杂度O(3^q*n*q)

    转移的时候发现需要知道从一个点走到另一个点的最短路,所以事先flyod预处理最短路就ok了

    E、景区路线规划(loj6178)

    分析:

    首先h1,h2明显独立,可以分开考虑,做两次即可

    最直观的想法是dp[now][time]表示我已经玩完了now点的游乐设施,还剩下时间time

    那么dp[now][time]=Σdp[u][t]/u点此时的出度 + h[now]

    这样会发现结果明显大很多,为什么呢?

    实际上,加的应该是h[now]*p[now][time],p[now][time]表示该种情况发生的概率

    因为h[now]发生是有概率的,如果直接加上h[now],那就是默认这事件发生概率是1了

    有个更简单的方法,就是直接dp[now][time]表示概率,不表示期望

    那么转移就是dp[now][time]=Σdp[u][t]/u

    期望怎么统计?

    ans=Σdp[now][time]*h[now]

    在time时间,我游完now,这可以当作所有事件,对应事件的权值就是我刚游完的那个设施的价值,所以这样求期望是可行的

    F、子串

    分析:

    直接kmp

  • 相关阅读:
    VMware虚拟机的三种连接方式
    Codeblocks16.01配置wxWidgets3.0.4
    DAO编程(VC6.0中的应用)
    VC++ 中用ado连接数据库
    C中文件的输入输出与C++的文件流
    Cpp中流继承关系
    a标签置灰不可点击
    手动操作数据库
    $.ajaxFileUpload is not a function
    【工具】手机号码、电话号码正则表达式
  • 原文地址:https://www.cnblogs.com/wmrv587/p/7096442.html
Copyright © 2011-2022 走看看