zoukankan      html  css  js  c++  java
  • 10.4 牛客

    10.4 牛客


    T2 爆零 (惨..

    毒瘤初始化 SB 复杂度

    挂分少的原因是因为无分可挂???


    考试过程

    题目时间不均匀... T2 和 T3 基本各分了一个多小时的时间 然后没有然后了


    一开始以为 T1 是个数论题 后来发现是个图论题...

    考完之后发现是个打表结论题???

    写了个最短路 发现过不了第三个样例... 改了一下还是过不了 想不出什么优化来就跑路了

    看了一眼 T2 发现暴力只有卑微的十分 这... 溜了溜了

    然后看 T4

    好像不是很可做的亚子 暴力敲完跑路了 随缘过..

    T3 感觉...

    好像能写...

    好像能写 好像真的能写

    然后一个小时之后还在能写的状态...

    看了一眼时间 打完暴力跑路了

    回头看 T2 直接尝试开后面的分了

    然后感觉可以 dp 然后就 dp 了 然后没调出来 然后就爆零了 其实那个十分的暴力也写了 但是并没有改变爆零的结果(

    又回头卡了一下 T1 还是不知道怎么优化...


    得分情况

    50 + 0 + 20 + 30 = 100

    T2 的十分挂没了...

    这套题的部分分分档有点玄学啊...


    题解

    T1 牛表

    (![)(*) 这你(**)说什么打表可证???(])(宣泄不满.jpg)


    通过打表发现答案非常小 不超过 (30)

    所以转移的时候只需要转移到 (left[max(1, u - lim), min(P - 1, u + lim) ight]) 范围内即可

    边数非常少 不需要用堆优化的迪杰 直接开队列

    复杂度 (O(P^2lim))


    代码


    T2

    也不知道出题人怎么想的...

    为什么 (n leq 1000) 的数据范围正解的复杂度是 (O(n^3)) 的啊...(虽然不影响爆零


    区间 (dp)

    状态设的非常玄学

    (f_{l, r}) 表示操作区间 ([l, r]) 的最小代价

    每次操作会把区间分成两个互不影响的部分 转移枚举操作位置

    [f_{l, r} = minleft(f_{l, k - 1} + f_{k + 1, r} + max(l, k - 1) + max(k + 1, r) ight) ]

    对应的 设 (g_{l, r}) 表示操作区间 ([l, r]) 得到最小代价的方案数

    (f) 转移的时候记录一下转移的位置 再对 (g) 进行转移即可

    [g_{l, r} = sum g_{l, k - 1} imes g_{k + 1, r} imes {r - l choose k - l} ]

    后面那个组合数是因为两区间之间的操作顺序是不确定的

    具体来说 在每个区间内部的操作顺序一定确定 但是对于两个区间可以在 (k) 左边操作一次 再在 (k) 右边操作一次...

    具体代码实现的时候可能会有转移越界的时候 然后边界或者初始换的位置就会出点问题 弄不好的话有可能就爆零了... 不要问怎么知道的

    复杂度 (O(n^3))


    这一部分的代码


    期望得分 (70) (实际上过了 (80)

    毕竟数据范围是 (1000)


    其实正解的复杂度也是 (O(n^3))

    引入贪心: 每个区间中先操作区间的最大值是最优的

    所以直接记录每个区间最大值的位置 只枚举最大值进行转移

    复杂度上界依旧是 (O(n^3)) 的 但实际会快很多


    代码


    T3

    咕~


    T4

    在边长进行扩展的过程中 不同数量的数只会增加不会减少 所以矩阵中数字的个数是单调增加的 然后题目中的矩阵又是一个正方形 所以可以固定正方形的右上角 然后二分正方形的边长 找到数字个数小于某个值的矩阵个数

    所以可以差分的考虑 答案就是 (leq K) 的矩阵个数减去 (leq K - 1) 的矩阵个数

    具体一个矩阵中有多少个数字 数字的种类不超过一百个 开 (bitset) 强压 然后用二维 (st) 表维护 就可以方便的查询了


    代码


    bitset

    类似数组的结构 每个元素只有 (0)(1) 每个元素只占 1 bit 的空间

    构造

    bitset <N> a; //无参构造
    bitset <N> b(x); //将 x 转化为二进制存储 不足在前面补 0 超出取后面的
    bitset <N> c(s); //将 01 串 s 前 N 为存储 不足在前面补 0 
    

    其中 (s) 可以为 char 也可以为 string 但是必须是 01

    操作

    [], ==, !=, &, &=, |, |=, ^, ^=, ~, <<, <<=, >>, >>=, <>

    下标访问 两个 bitset 是否相等 所有的位运算 cin/cout 输入输出

    函数

    bitset <N> a;
    a.count(); // 1 的数目
    a.size(); // 大小 N
    a.test(x); // 取下标为 x 位置的元素 会对下标是否越界做出检查 比 [] 安全
    a.any(); // 是否存在 1
    a.none(); // 是否不存在 1
    a.all(); // 是否全是 1 (C++11
    a.set(); // 全置为 1
    a.reset(); // 全置为 0
    a.flip(); // 翻转每一位
    
  • 相关阅读:
    mysql添加用户
    ubantu更新源
    内存的crash记录分析
    windows下sublime2 clojure环境配置
    服务器使用recast navigation
    网络库crash以及boost asio strand dispath分析
    CentOS7 监控进程网络流量工具安装
    vs2013提高编译速度
    Centos6.5 gitlab安装使用
    linux命令行将已有项目提交到github
  • 原文地址:https://www.cnblogs.com/blank-space-/p/15395317.html
Copyright © 2011-2022 走看看