zoukankan      html  css  js  c++  java
  • 计数dp与容斥

    本文参考自[彭博-问题的常用技巧]

    I.条件计数

    • 问题最难的点一般有两种途径,不重不漏的计数和容斥,如果要不重不漏的计数就要寻找一个唯一能表示计算的目标的量

    1.CF1264D2

    递归定义合法括号序列及其深度:

    • 空串是合法括号序列,深度为 0 。

    • 如果 s 是合法括号序列,那么 (s) 也是合法括号序列,深度
    为 s 的深度加一。

    • 如果 s,t 是合法括号序列,那么 st 也是合法括号序列,深度
    为 s,t 的深度的较大值。

    定义任意一个括号序列的深度为其所有合法括号子序列的深度的
    最大值。
    给出一个包含 ()? 的字符串,? 可以任意替换为) 或 ( ,求出每
    一种替换方案的深度之和。
    (n ≤ 10^6)

    solution

    考虑假设我们已知一个括号序列(不一定合法),如何计算其深度

    可以发现最优方案一定包含一个((((((((......))))))))的形式,满足左括号和右括号数相等且一一对应

    容易想到枚举中间的那个位置,然后算一下即可

    2.AGC052C Nondivisible Prefix Sums

    给定质数 P 和长度 n 。

    对于 ((P-1)^n) 个值域在 ([1, P-1]) 的数列,称它是好的,当且仅
    当存在一种方法把它重排,使得每个前缀和都不是 P 的倍数。
    求好的数列个数。

    (1 ≤ n ≤ 5000, 3 ≤ P ≤ 10^8)

    solution

    AGC yyds!很妙的题

    首先如果和是 P 的倍数,那么一定不行

    我们考虑这么一种构造方法

    每次取剩余出现次数最多的数去填,不行就换次多的,注意到这种方法会不合法当且仅当后面填 x 不合法且数列中仅剩 x

    注意到根据这种方法,如果众数出现次数(leq n / 2),那么一定合法,这个可以用数学归纳法证明

    我们考虑将众数消到(leq frac{n}{2}),不妨设众数为1(如果不是就所有数都乘以逆元),我们考虑一直填 1 ,如果不行就换一个数,注意不行是,前缀和必然为 (P-1) ,如果此时填 (a_i) ,那么还能填 (P-a_i) 个 1 ,那么如果 (cnt1 leq sum_i(P - a_i)(a_i != 1) + P - 1),则必然可以

    反之,若不满足,则将所有数都消耗完依然剩下1,那么必定不合法

    得到充要条件后,因为无法同时记录(sum_i a_i mod P)(sum_i (P - a_i)),我们不妨计算钦定总和不为 P 的倍数且不合法的方案数,那么(sum (P -a_i) < n),做一下背包即可,最后用总数((P-1)^{n-1}*(P-2))减去背包方案的 P - 1倍即可(因为我们强行钦定众数为 1 )

    3.[AGC043D] Merge Triplets

    题意简述:

    • 给定 n ,求长度为 3n 的能被以下方法生成的排列个数。

    • 生成 n 个长度为 3 的数列,使得每个 1 到 3n 中的数恰好被用一次。

    • 生成一个初始为空的数列 P ,重复以下操作 3n 次:

    • 在所有非空数列的开头中选取最小的元素 x 。

    • 把 x 加入到 P 的末尾,并从原数列删去。

    (n ≤ 2000)

    首先我们思考假设我们已经有数列了该如何生成 P

    必然是归并排序,模拟归并排序的过程,就是按照前缀最大值分成若干个长度为1/2/3的段
    ,然后整段按照前缀最大值从小到大排序

    那么我们可以改写题意,称一个排列 P 是合法的,当且仅当它可以被分成若干个长度为 1 / 2 / 3的段,段首单调递增,且一的段个数要大于二的段的个数

    倒过来 dp ,设 (dp_{i,j})表示 dp 到 i ,第一个段个数比第二个段多 j

    因为最后一段段首必然是全局最大值,根据这个转移即可

    总结:

    大概分析一下这种条件计数不重不漏的方法(即不包含容斥)

    • 先分析题目性质,思考构造过程

    • 根据构造过程,转化题意,寻找更简洁的充分条件(难点)

    • 根据充分条件 dp (基本功)

    分析性质,转化题意这一步在很多其他题目中都有应用,基本功也是必须掌握好的

    II.容斥

    1.AGC041F

    题解:solution

    2.ARC096E

    套公式仔细分析即可

    简单题,但是有一点要注意,只包含空集的集合不是空集

  • 相关阅读:
    源码分析— java读写锁ReentrantReadWriteLock
    7. SOFAJRaft源码分析—如何实现一个轻量级的对象池?
    深入理解Kafka必知必会(2)
    6. SOFAJRaft源码分析— 透过RheaKV看线性一致性读
    5. SOFAJRaft源码分析— RheaKV中如何存放数据?
    深入理解Kafka必知必会(1)
    4. SOFAJRaft源码分析— RheaKV初始化做了什么?
    3. SOFAJRaft源码分析— 是如何进行选举的?
    2. SOFAJRaft源码分析—JRaft的定时任务调度器是怎么做的?
    pinpoint1.8.5安装及使用指南
  • 原文地址:https://www.cnblogs.com/y-dove/p/14851822.html
Copyright © 2011-2022 走看看