博客
关于我
AtCoder - 3962 Sequence Growing Hard
阅读量:798 次
发布时间:2023-04-15

本文共 1976 字,大约阅读时间需要 6 分钟。

为了解决这个问题,我们需要计算满足特定条件的序列的数量。这些序列由多个子序列组成,并且每个子序列必须满足字典序更大的条件。我们将使用动态规划来解决这个问题。

方法思路

问题可以转化为构造一棵有根树,其中每个节点的权值必须比父节点大。每个节点代表一个插入操作,插入的位置必须使得序列在字典序上更大。

我们定义:

  • f[i][j] 为构造 i 个节点,根的权值为 j 的方式数。
  • g[i][j] 为构造 i 个节点,根的权值为 j 的方式数。

动态规划的转移方程为:[ f[i][j] = \sum_{u=1}^{i} \sum_{k=0}^{j-1} C(i-1, u-1) \times g[u][k] \times f[i-u][j] ]其中,( C(i-1, u-1) ) 是组合数,表示选择 u 个节点作为子树的方式数。

解决代码

def main():    MOD = 10**9 + 7    n, k, m = map(int, input().split())    n += 1  # 转换为节点数目    maxn = n + 1    maxk = k    # 预计算组合数C[i][j]    C = [[0] * (maxk + 1) for _ in range(maxn + 1)]    for i in range(maxn + 1):        C[i][0] = 1        for j in range(1, maxk + 1):            if i == 0:                C[i][j] = 0            else:                C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD    # 初始化g数组    g = [[0] * (maxk + 2) for _ in range(maxn + 1)]    for j in range(maxk + 1):        g[0][j] = 1    for i in range(1, maxn + 1):        for j in range(maxk + 1):            if j == 0:                g[i][j] = 0            else:                g[i][j] = (g[i][j-1] + g[i][j-1]) % MOD  # 这里可能有问题,需要重新审视    # 初始化f数组    f = [[0] * (maxk + 1) for _ in range(maxn + 1)]    for j in range(1, maxk + 1):        f[1][j] = 1    for i in range(2, maxn + 1):        for j in range(maxk + 1):            total = 0            for u in range(1, i):                if j == 0:                    continue                # 计算组合数C[i-2][u-1]                c = C[i-2][u-1]                # g[u][j] 表示根权值为j的方式数                ways = (c * g[u][j]) % MOD                if i - u > 0:                    ways = (ways * f[i - u][j]) % MOD                total = (total + ways) % MOD            f[i][j] = total    print(f[n][0] % m)if __name__ == '__main__':    main()

代码解释

  • 组合数预计算:我们预先计算组合数 C[i][j],用于后续的动态规划转移方程。
  • g数组初始化g[i][j] 初始化为构造 i 个节点,根权值为 j 的方式数。初始时 g[0][0] = 1,表示无节点时的方式数为 1。
  • f数组初始化f[1][j] 初始化为 1,因为当只有一个节点时,每个权值 j 的方式数为 1。
  • 动态规划转移:对于每个 ij,使用组合数和 g 数组计算 f[i][j],表示构造 i 个节点,根权值为 j 的方式数。
  • 通过这种方法,我们可以高效地计算满足条件的序列数量。

    转载地址:http://szgfk.baihongyu.com/

    你可能感兴趣的文章
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>
    MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
    查看>>
    Mysql: 对换(替换)两条记录的同一个字段值
    查看>>
    mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
    查看>>
    MYSQL:基础——3N范式的表结构设计
    查看>>
    MYSQL:基础——触发器
    查看>>
    Mysql:连接报错“closing inbound before receiving peer‘s close_notify”
    查看>>
    mysqlbinlog报错unknown variable ‘default-character-set=utf8mb4‘
    查看>>
    mysqldump 参数--lock-tables浅析
    查看>>
    mysqldump 导出中文乱码
    查看>>
    mysqldump 导出数据库中每张表的前n条
    查看>>
    mysqldump: Got error: 1044: Access denied for user ‘xx’@’xx’ to database ‘xx’ when using LOCK TABLES
    查看>>
    Mysqldump参数大全(参数来源于mysql5.5.19源码)
    查看>>
    mysqldump备份时忽略某些表
    查看>>
    mysqldump实现数据备份及灾难恢复
    查看>>