[JXOI2017]数列
一个不太一样的做法
当\(A_{i-1}=x\),称\(A_1\)到\(A_{i-2}\)中大于等于\(A_{i-1}\)的最小值\(R\)为上界,\(A_1\)到\(A_{i-2}\)中小于等于\(A_{i-1}\)的最大值\(L\)为下界。对于一组\((L,R,x)\)显然有\(L\leq x\leq R\),我们下一个能填的数也只能在这个范围内。
当我们\(A_i=y\)的时候,考虑新的上下界分别是谁。
当\(x\leq y\leq R\)的时候,显然小于等于\(y\)中最大的是\(x\),大于等于\(y\)中最大的是\(R\),所以新的下界是\(x\),上界\(R\),三元组变成了\((x,R,y)\)
当\(L\leq y< x\)的时候,新的上界是\(x\),下界是\(L\),三元组变成了\((L,x,y)\)
到这里我们就可以写一个dp了,设\(f_{i,j,k,p}\)表示填了\(i\)个数,末尾三元组的状态是\((j,k,p)\),转移的时候枚举下一位填什么推出下一个三元组即可。状态数是\(O(nr_i^3)\),转移是\(O(r_i)\)的,复杂度是\(O(nr_i^4)\)不是很能接受
再观察一下这个dp的转移,发现它非常别致,我们枚举下一位填的数\(y\)
当\(p\leq y\leq k\),\(f_{i,j,k,p}\)向\(f_{i+1,x,k,y}\)转移,这个转移和\(j\)这一维没有关系
当\(j\leq y< p\),\(f_{i,j,k,p}\)向\(f_{i+1,j,x,y}\)转移,这个转移和\(k\)这一维没有关系
考虑一下是否可以去掉一维,上下界中只保存一个能否进行转移
显然是可以的,设\(dp_{i,j,k}\)表示当前填了\(i\)个数,上/下界为\(j\),末尾填的数为\(k\)。我们强行规定当\(k\leq j\)的时候,\(j\)为上界;当\(k>j\)的时候,\(j\)为下界
即对于原来的\(f_{i,j,k,p}\)拆分成了两个状态\(dp_{i,j,p}\)和\(dp_{i,k,p}\),这两个状态各自完成\(f_{i,j,k,p}\)的一部分转移。其中\(dp_{i,j,p}\)负责\(j\leq y<p\)的转移;\(dp_{i,k,p}\)负责\(p\leq y\leq k\)的转移。注意转移之后得到的仍旧是一个完整的上下界都有的状态,我们还是要把这个状态拆分一下。
转移的时候还是枚举下一位填什么数,根据填的数推出转移的状态即可。注意当一下位填的数和上下界相等时,新的上下界就固定了。
这样的状态数就变成了\(O(nr_i^2)\),复杂度是\(O(nr_i^3)\),不知道为什么跑的比较快,luogu最优解,loj位列rk3
代码
#include<bits/stdc++.h>
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=155;
const int mod=998244353;
inline int qm(int x) {return x>=mod?x-mod:x;}
int h[55],n,o,R,dp[2][maxn][maxn];
int main() {
n=read();for(re int i=1;i<=n;i++) h[i]=read(),R=max(R,h[i]);R++;
for(re int i=1;i<=h[2];++i)
for(re int j=1;j<=h[1];++j) {
if(j>=i) {if(i!=j) dp[0][i][0]++;}
else dp[0][i][R]++;
dp[0][i][j]++;
}
for(re int i=3;i<=n;i++,o^=1) {
memset(dp[o^1],0,sizeof(dp[o^1]));
for(re int j=1;j<=h[i-1];j++)
for(re int k=0;k<=R;++k) {
if(!dp[o][j][k]) continue;
if(k<j) {
for(re int p=k;p<j;p++)
if(p<=h[i]&&p>0) {
if(p==k) {
dp[o^1][p][p]=qm(dp[o^1][p][p]+dp[o][j][k]);
continue;
}
dp[o^1][p][k]=qm(dp[o^1][p][k]+dp[o][j][k]);
dp[o^1][p][j]=qm(dp[o^1][p][j]+dp[o][j][k]);
}
}
else {
for(re int p=j;p<=k;++p)
if(p<=h[i]&&p>0) {
if(p==j||p==k) {
dp[o^1][p][p]=qm(dp[o^1][p][p]+dp[o][j][k]);
continue;
}
dp[o^1][p][j]=qm(dp[o^1][p][j]+dp[o][j][k]);
dp[o^1][p][k]=qm(dp[o^1][p][k]+dp[o][j][k]);
}
}
}
}
int ans=0;
for(re int i=1;i<=h[n];++i)
for(re int j=i;j<=R;++j) ans=qm(ans+dp[o][i][j]);
return !printf("%d\n",ans);
}
[JXOI2017]数列的更多相关文章
- [P4063][JXOI2017]数列(DP)
题目描述 九条可怜手上有一个长度为 n 的整数数列 ri,她现在想要构造一个长度为 n 的,满足如下条件的整数数列 A: • 1 ≤ Ai ≤ ri. • 对于任意 3 ≤ i ≤ n,令 R 为 A ...
- 洛谷P4063 [JXOI2017]数列(dp)
题意 题目链接 Sol 这题想还是不难想的,就是写起来很麻烦,然后去看了一下loj的最短代码表示只能Orz 首先不难发现一条性质:能够选择的区间一定是不断收缩的,而且新的可选区间一定是旧区间的某个位置 ...
- AHOI2018训练日程(3.10~4.12)
(总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...
- [JXOI2017]颜色 线段树求点对贡献
[JXOI2017]颜色 题目链接 https://www.luogu.org/problemnew/show/P4065 题目描述 可怜有一个长度为 n 的正整数序列 Ai,其中相同的正整数代表着相 ...
- [BZOJ5011][JXOI2017]颜色
5011: [Jx2017]颜色 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 84 Solved: 46[Submit][Status][Disc ...
- C#求斐波那契数列第30项的值(递归和非递归)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- BZOJ1500[NOI2005]维修数列
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- PAT 1049. 数列的片段和(20)
给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1 ...
- 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)
对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...
随机推荐
- 创建调用Consul的客户端项目
创建调用Consul的客户端项目 创建项目 源码 Github仓库:https://github.com/sunweisheng/spring-cloud-example
- 关于dom获取元素的几种方式
原文链接:https://blog.csdn.net/levinhax/article/details/71274456 获取元素DOM对象有很多种方法,以前一直在用getElementById和ge ...
- Vue小白篇 - ES6的语法
为什么要学 ES6 的语法呢? 因为 Vue 语法有很多都是 ES6(ECMAScript 6),这里推荐 [阮一峰 ECMAScript 6 入门]: http://es6.ruanyifeng.c ...
- noip2010机器翻译
以下题面摘自洛谷1540 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换. ...
- [HTML知识体系]语义化标签概论
1.什么是语义化 语义化(Semantic)在HTML5中被大量提起,就是语义化标签向浏览器和开发者展示了它所包裹内容的类型与意思,可是至今我看了好多代码,HTML5新增的语义化标签的使用率还是挺低的 ...
- 浅谈maven自动化构建工具
转载https://blog.csdn.net/zxm1306192988/article/details/76209062 Maven是什么[what] 1.Maven 是 Apache 软件基金会 ...
- 0001.第一个多线程demo--分批处理数据
public class UserEntity { private String userId; private String userName; public String getUserId() ...
- pdfminer实现pdf布局分析 python (pdfminer realize layout analysis with PDF python)
使用pdfminer实现pdf文件的布局分析 python 参考资料: https://github.com/euske/pdfminer https://stackoverflow.com/ques ...
- php图片无损压缩的问题解决
代码如下 <?php namespace App\Contract; use Carbon\Carbon; /** * 图片压缩封装类 * @author jackie <2019.11. ...
- Concurrent - 多线程
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11426916.html Java中有几种方法可以实现一个线程? 继承Thread类(不支持多继承) 实 ...