题目

一个不太一样的做法

当\(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]数列的更多相关文章

  1. [P4063][JXOI2017]数列(DP)

    题目描述 九条可怜手上有一个长度为 n 的整数数列 ri,她现在想要构造一个长度为 n 的,满足如下条件的整数数列 A: • 1 ≤ Ai ≤ ri. • 对于任意 3 ≤ i ≤ n,令 R 为 A ...

  2. 洛谷P4063 [JXOI2017]数列(dp)

    题意 题目链接 Sol 这题想还是不难想的,就是写起来很麻烦,然后去看了一下loj的最短代码表示只能Orz 首先不难发现一条性质:能够选择的区间一定是不断收缩的,而且新的可选区间一定是旧区间的某个位置 ...

  3. 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题) ...

  4. [JXOI2017]颜色 线段树求点对贡献

    [JXOI2017]颜色 题目链接 https://www.luogu.org/problemnew/show/P4065 题目描述 可怜有一个长度为 n 的正整数序列 Ai,其中相同的正整数代表着相 ...

  5. [BZOJ5011][JXOI2017]颜色

    5011: [Jx2017]颜色 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 84  Solved: 46[Submit][Status][Disc ...

  6. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. BZOJ1500[NOI2005]维修数列

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  8. 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 ...

  9. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

随机推荐

  1. python删除某一行

    整理了网络上的一些方法,一般有两种方法:第一种:是先把文件读入内存,在内存中修改后再写入源文件. 例子:将内容包含“123”的所有行删去: with open('C:/Users/lai/Deskto ...

  2. VINS 回环检测与全局优化

    回环检测 VINS回环检测与全局优化都在pose_graph.cpp内处理.首先在pose_graph_node加载vocabulary文件给BriefDatabase用,如果要加载地图,会loadP ...

  3. C#解惑:HashSet<T>类

    原贴: https://blog.csdn.net/X_X_OO/article/details/52529548 https://www.cnblogs.com/refuge/p/9465466.h ...

  4. Node中的Cookie和Session

    1.Cookie HTTP是无状态协议.例:打开一个域名的首页,进而打开该域名的其他页面,服务器无法识别访问者.即同一浏览器访问同一网站,每次访问都没有任何关系. Cookie的原理是:客户端浏览器在 ...

  5. java 线程安全并发Queue

    并发Queue 在并发的队列上jdk提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论在那种都继承自Qu ...

  6. mysql基于GTIDS复制

    GTIDS的环境:一台master 192.168.200.111多个slave: 192.168.200.112 192.168.200.113 修改master服务器:[root@localhos ...

  7. 力扣——Next Permutation(下一个排列) python实现

    题目描述: 中文: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...

  8. svn解决方案

    1.svn回退 revert to this version 2.不同svn路径拉倒一个本地文件夹,报错"已经指向不同的url工作副本":  删除文件夹中的.svn文件夹 3.sv ...

  9. 【leetcode】756. Pyramid Transition Matrix

    题目如下: We are stacking blocks to form a pyramid. Each block has a color which is a one letter string, ...

  10. Nacos 1.1.4 发布,业界率先支持 Istio MCP 协议

    Nacos是阿里巴巴开源的服务发现与配置管理项目,本次发布的1.1.4版本,主要带来的是与Istio的对接功能,使用的是Istio最新的MCP协议.本文将介绍包括这个功能在内的新版本发布的功能. 升级 ...