Hetao P1031 萌萌题 题解 [ 蓝 ] [ 线性 dp ]
萌萌题:一道结合了观察性质的线性 dp。

观察
我们先考虑极端情况:所有数相同,所有数降序排列两种情况。
对于所有数相同的情况,我们发现,最终可以合并出来的区间,最多只有 \(n \log n\) 个。
怎么证明?考虑固定右端点,那么我们想要合并出一个点,就得选 \(2^k\) 个数出来,这就有 \(\log n\) 次选择方式。总的来说就是有 \(n \log n\) 种选数方式了。
所有数降序排列是多少?我们只需要将最后两个元素合并,然后继续往前面合并即可。总体来说有 \(n\) 个。
dp 设计
这题还有个很重要的观察:对于固定了右端点的时候,假设我们要让这个数增加 \(v\),那么合并的方案(区间)一定是唯一的。这就启发了我们可以设计一个 dp,定义 \(dp_{i,j}\) 表示让元素 \(i\) 增加 \(j\) 后,合并到的区间的左端点的前一个数是哪里。
为什么要前一个数?其实你不要这前一个数其实也可以做。只不过我这样设计来讲比较好写转移的代码。
接下来就是很显然的转移,假设目前合并到的区间的左端点的前一个数为 \(now\),要增加 \(v\):
\]
然后记录一下合法状态就好了。
这样写对吗?实际上假了。这是我赛时的做法,当时误以为一个数最多增量只可能是 \(\log n\)。实际上降序排列就能把增量卡到 \(n\)。
那么开大小为 \(n\) 的增量可不可以?直接开肯定不行,会 MLE,但是动态开不就行了?根据前面的观察,我们最多只有 \(n \log n\) 个合法区间,那么每个数的增量也最多只有 \(n \log n\) 个,我们用 vector 模拟动态开 dp 数组的过程,这道题就 AC 了。
注意,当某个区间无法继续合并下去的时候,要立刻 break,才能保证复杂度正确,否则会退化为平方级别。
时间复杂度为 \(O(n\log n)\)。
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
int n,a[100005],ans=0;
vector<int>dp[100005];
int main()
{
freopen("cute.in","r",stdin);
freopen("cute.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)
{
dp[i].emplace_back(i-1);
for(int j=1;j<=100000;j++)
{
int now=dp[i][j-1];
int ta=a[now];
int dt=a[i]+j-1-ta;
if(dt>=0&&dt<dp[now].size())dp[i].emplace_back(dp[now][dt]);
else break;
}
}
for(int i=1;i<=n;i++)ans=max(ans,a[i]+int(dp[i].size())-1);
cout<<ans<<endl;
return 0;
}
Hetao P1031 萌萌题 题解 [ 蓝 ] [ 线性 dp ]的更多相关文章
- 【AHOI2009】中国象棋 题解(线性DP+数学)
前言:这题主要是要会设状态,状态找对了问题迎刃而解. --------------------------- 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可 ...
- 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)
ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...
- 单调队列+线性dp题Watching Fireworks is Fun (CF372C)
一.Watching Fireworks is Fun(紫题) 题目:一个城镇有n个区域,从左到右1编号为n,每个区域之间距离1个单位距离节日中有m个烟火要放,给定放的地点ai,时间ti当时你在x,那 ...
- cf909C 线性dp+滚动数组好题!
一开始一直以为是区间dp.. /* f下面必须有一个s 其余的s可以和任意f进行匹配 所以用线性dp来做 先预处理一下: fffssfsfs==>3 0 1 1 dp[i][j] 表示第i行缩进 ...
- [线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题
题目来源: Codeforces - 1110D 题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌 思路: 1.三组[ ...
- 洛谷P1140 相似基因(线性DP)
题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了444种核苷酸,简记作A,C,G,TA,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类 ...
- 线性dp
线性dp应该是dp中比较简单的一类,不过也有难的.(矩乘优化递推请出门右转) 线性dp一般是用前面的状态去推后面的,也有用后面往前面推的,这时候把循环顺序倒一倒就行了.如果有的题又要从前往后推又要从后 ...
- ACM ICPC 2018 青岛赛区 部分金牌题题解(K,L,I,G)
目录: K Airdrop I Soldier Game L Sub-cycle Graph G Repair the Artwork ———————————————————— ps:楼主脑残有点严 ...
- [CodeForces - 1272D] Remove One Element 【线性dp】
[CodeForces - 1272D] Remove One Element [线性dp] 标签:题解 codeforces题解 dp 线性dp 题目描述 Time limit 2000 ms Me ...
- P3387缩点(tarjan+拓扑排序+线性dp)
题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...
随机推荐
- npm run build命令运行后报错 npm ERR! missing script: build
打开vue项目中的package.json查看一下script的设置,是否如下图 如果是的话,那么运行打包命令的时候要运行 npm run build:prod --report
- WinForm(C/S)项目中使用矢量字体(FontAwsome、Elegant)图标
1.介绍 字体图标在Web应用中最为常见,字体图标是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真.字体图标常见的有Font Awesome和Elega ...
- Net中手写 事件总线 发布订阅消息
Net 手写 事件总线 发布订阅消息 前言 今晚打老虎 事件总线是对发布-订阅模式的一种实现.它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的.(项目的 ...
- 前端每日一知之css常用布局单位
脑图在线链接 本文内容依据[js每日一题]公众号精彩文章总结而来
- VTK vtkAssembly 拾取
在有vtkAssembly的拾取中,vtkAssembly的Pickable决定子Actor能否被拾取.跟子Actor的Pickable没有关系
- 鸿蒙UI开发快速入门 —— part03: 组件的生命周期
1. 什么是组件的生命周期 组件的生命周期是我们开发一个组件必须要关注的内容,组件的生命周期,指的是组件的创建.渲染.销毁等过程.因为这个过程就类似于人从出生到离世的过程,从而称为:组件的生命周期. ...
- R机器学习:朴素贝叶斯算法的理解与实操
最近又看了很多贝叶斯算法的一些文章,好多的文章对这个算法解释起来会放一大堆公式,对代数不好的人来说真的很头疼.本文尝试着用大白话写写这个算法,再做个例子,帮助大家理解和运用. Naive Bayes ...
- 2024年1月Java项目开发指南1:环境与工具准备
准备工作 基础能力 开发能力的事咱先不谈,有两个基础技能要学一下. 1.学习使用Markdown编写文档 2.学会使用git拉取代码和提交代码 软件准备 电脑需要安装以下软件: IDEA 2023.2 ...
- resttemplate 调用https 出错 unable to find valid certification path to requested target
resttemplate 调用https使用下面代码: @Bean @Primary public RestTemplate restTemplate(ClientHttpRequestFactory ...
- Linux 中的内存使用率计算方式
背景介绍 在工作中处理问题的时候,遇到一个问题,自己根据 top 命令时查看到的 used 和 total 计算出来的内存使用率已经达到 90% 以上了,但是系统自带的监控软件计算出来的使用率往往没有 ...