首页 > 其他分享 >序列 DP

序列 DP

时间:2024-03-13 17:15:13浏览次数:22  
标签:le sum 枚举 序列 Theta 复杂度 DP

(1) LOJ P507 接竹竿

  • 有 \(n\) 张牌排成一排,每张牌有属性 \((c_i, v_i)\)。保证 \(c_i \le k\)。

    每次操作选择两张牌 \(l, r\) 满足 \(c_l = c_r\),删除 \(l \sim r\) 中的所有牌,并获得 \(\sum_{i=l}^rv_i\) 的收益。

    求最大的收益。

  • \(n, k \le 10^6\)。

设状态 \(f_i\) 表示若只考虑前 \(i\) 张牌,能获得的最大收益。

转移枚举第 \(i\) 张牌是否是在最后一次操作中被删,以及被哪个区间删。即 \(f_{i - 1}\) 和 \(\max_{j=1}^{i - 1}\{f_{j - 1} + \sum_{k=j}^iv_k \mid c_i = c_j\}\) 的较大值。

直接做是 \(n^3\) 的。区间求和那个部分可以前缀和优化,但仍然是 \(n^2\) 的,即 \(\max_{j=1}^{i - 1}\{f_{j - 1} + \sum_{k=1}^iv_k - \sum_{k=1}^{j-1}v_k \mid c_i = c_j\}\)。

可以把与 \(j\) 无关的提到外面,即 \(\sum_{k=1}^iv_k + \max_{j=1}^{i - 1}\{f_{j - 1} - \sum_{k=1}^{j-1}v_k \mid c_i = c_j\}\)。

然后这个就很好维护了。我们用桶维护每个 \(c_i\) 所对应的最大的 \(f_{i-1} - \sum_{k=1}^{i-1}v_k\),转移可以优化成 \(\Theta(1)\)。总时间复杂度 \(\Theta(n)\)。

(2) P4342 [IOI1998] Polygon

  • 有一个 \(n\) 个顶点 \(n\) 条边的环,顶点上有数字,边上有 \(+, \times\) 两种运算符号。

    首先删掉一条边,然后每次选择一条连接 \(V_1, V_2\) 的边,用边上的运算符计算 \(V_1\) 和 \(V_2\) 得到的结果来替换这两个顶点。

    求最后元素的最大值。

  • \(n \le 50\)。

显然区间 DP。首先倍长破环为链。

设状态 \(f_{l, r}\) 表示将区间 \(l \sim r\) 内的数字处理后得到的最大数字。转移枚举断点 \(k\),即 \(f_{l, r} = \max_{k=l}^{r-1} \operatorname{opt}(f_{l, k}, f_{k + 1, r})\),其中 \(\operatorname{opt}\) 表示边上的运算符号。

这样做是不正确的。注意到两个负数相乘结果为正数,所以再维护 \(g_{l, r}\) 表示最小值。转移类似。

复杂度 \(\Theta(n^3)\)。

(3) P4933 大师

  • 给定一个长度为 \(n\) 的序列。求有多少个子序列是等差数列。
  • 设 \(v\) 为序列最大值。\(n \le 1000\),\(v \le 20000\)。

设状态 \(f_{i, j}\) 表示有多少个以 \(i\) 结尾的子序列是公差为 \(j\) 的等差数列,且长度大于 \(1\)。

转移枚举倒数第二个元素 \(k\),即 \(f_{i, j} = \sum_{k=1}^{i - 1} \{f_{k, j} + 1\mid a_i - a_k = j\}\)。其中 \(+1\) 的原因是我们可以选择长度为 \(1\) 的子序列。

复杂度是 \(\Theta(n^2v)\) 的。考虑优化。

可以发现如果确定了 \(a_i, j\) 那么 \(a_k\) 的值是可以确定的,即 \(a_k = a_i - j\)。所以处理方法与 (1) 类似,维护桶表示每一个 \(a_i\) 对应的 \(f_{i, j} + 1\) 之和。注意这里还有一个未处理的 \(j\),解决方法是将转移顺序改为先枚举 \(j\) 再枚举 \(i\)。这样在当前 \(j\) 这轮循环时就不需要考虑 \(j\) 的影响了。

时间复杂度 \(\Theta(nv)\)。

标签:le,sum,枚举,序列,Theta,复杂度,DP
From: https://www.cnblogs.com/2huk/p/18071042

相关文章

  • 【算法】【线性表】【数组】从中序与后序遍历序列构造二叉树
    1 题目给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。示例1:输入:inorder=[9,3,15,20,7],postorder=[9,15,7,20,3]输出:[3,9,20,null,null,15,7]示例2:输入:inor......
  • JSON序列化之旅:深入理解.NET中的JsonResult与自定义ContractResolver
    在.NET开发的世界里,JSON已成为一种无处不在的数据交换格式。无论是WebAPI还是微服务架构,我们都经常需要将对象序列化成JSON格式,以方便客户端的接收和处理。今天,我想和大家分享一段关于.NET中JsonResult使用的代码,以及它背后的一些细节。这段代码来自于一个典型的ASP.NETCore应......
  • Offer必备算法13_路径dp_六道力扣题详解(由易到难)
    目录①力扣62.不同路径解析代码②力扣63.不同路径II解析代码③力扣LCR166.珠宝的最高价值解析代码④力扣931.下降路径最小和解析代码⑤力扣64.最小路径和解析代码⑥力扣174.地下城游戏解析代码本篇完。①力扣62.不同路径62.不同路径难度中等一个......
  • 01-列表操作-使用slice()命名切片,增强程序可读及可维护性,兼使用indices()方法,防止出现
    程序中的切片,使用原始的索引访问时,如果数量过多,时间久了,就会导致难以阅读和维护。但使用slice()函数,创建【命名切片】后,赋予了切片与现实相近的名称,让程序更容易理解。同时,slice类中的indices方法,返回start,stop,step,3个值组成的元组。并且indices()对3个值进行自动调整,确......
  • 从CF1941D与1741E初探可达性DP
    Problem-D-Codeforces用记忆化搜索过的,然而DP能快300ms记忆化搜索|\(\texttt{set}\)模拟核心思路一致,都是通过定义一个状态,即在第t次到达第now点来去重剪枝记忆化搜索intn,m,x;std::vector<std::pair<int,char>>step;std::set<int>S;intgetClock(intx,......
  • 【Paper Reading】7.DiT(VAE+ViT+DDPM) Sora的base论文
    VAEDDPM 分类内容论文题目ScalableDiffusionModelswithTransformers作者WilliamPeebles(UCBerkeley),SainingXie(NewYorkUniversity)发表年份2023摘要介绍了一类新的扩散模型,这些模型利用Transformer架构,专注于图像生成的潜在扩散模型。这些......
  • 【算法训练营】最长公共子序列,倒水问题,奶牛吃草(Python实现)
    最长公共子序列时间限制:1sec空间限制:256MB问题描述给定两个1到n的排列A,B(即长度为n的序列,其中[1,n]之间的所有数都出现了恰好一次)。求它们的最长公共子序列长度。输入格式第一行一个整数n,意义见题目描述。第二行n个用空格隔开的正整数A[1],…,......
  • 【算法训练营】邓老师书,子序列,前缀(python实现)
    邓老师数时间限制:1sec空间限制:256MB问题描述众所周知,大于1的自然数中,除了1与其本身外不再有其他因数的数称作质数(素数)。对于大于1的不是质数的自然数,我们又称作合数。参加了邓老师算法训练营的小Z突发奇想,定义了新的数:所有合数中,除了1与其本身外,其他因......
  • Java序列化和反序列化
    1、编写Java代码解释什么是类继承2、编写Java代码解释什么是函数重写3、画图解释java,jsp,jar,class后缀都代表什么含义4、编写自己的序列化和反序列化方法实现java序列化反序列化5、重写readobject方法,要求在反序列化的时候输出自己姓名全拼6、对比PHP反序列化漏洞代码和J......
  • GDCM:实现使用gdcm::Series类进行DICOM的序列化和反序列化操作(附完整源码)
    GDCM:实现使用gdcm::Series类进行DICOM的序列化和反序列化操作下面是一个使用GDCM库中的gdcm::Series类进行DICOM序列化和反序列化操作的示例代码:#include<iostream>#include"gdcmReader.h"#include"gdcmWriter.h"#include"gdcmGlobal.h"#include"gdcmSystem.......