[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范围 ...
随机推荐
- CentOS7版本中locate: 未找到命令,详细解决方案
在学习Linux(CentOS7)文件搜索命令:locate 时,遇到错误“locate: 未找到命令”. 原因:CentOS7默认没有安装该命令 解决方案: 1.安装"locate&quo ...
- 百度分布式配置管理平台-Disconf
Disconf介绍 全称:Distributed Configuration Management Platform,即分布式配置管理平台. Disconf专注于各种分布式系统配置管理的通用组件和通用 ...
- js中获取input中所输入的值
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Codeforces Breaking Good
Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes Breaking Good is a n ...
- Nginx Web 基础入门
目录 Nginx Web 基础入门 Nginx快速安装 两种方式部署Nginx 如何升级nginx或者添加功能 使用systemd管理nginx nginx相关配置文件 nginx的配置文件详解 虚拟 ...
- 启动ABP项目
1.在官网下载ABP项目 2.打开项目选择解决方案,右击还原NuGet包 3.修改appsettings.json中的ConnectionStrings 例子"ConnectionStrin ...
- Bootstrap 警告框
<div class="panel panel-primary"> <div class="panel-heading"> <h3 ...
- Rectangle类详解
一,概括: 乍一看,可能感觉是一个矩形类,矩形类就是画一个长方形吗??这是我一开始见到这个类的感觉. 其实不是的Rectangle是一个“区域”类,它的最大作用就是定义一个矩形的区域,如果问为什么是矩 ...
- 【Flutter学习】之深入浅出 Key
一,前言 在开发 Flutter 的过程中你可能会发现,一些小部件的构造函数中都有一个可选的参数——Key.在这篇文章中我们会深入浅出的介绍什么是 Key,以及应该使用 key 的具体场景. 二,什么 ...
- Git Git管理码云项目
Git 一.下载安装 1. 要使用git 先安转git 请到官网下载最新git https://git-scm.com/downloads 2. 一路默认安装,安装完成右键查看下是否有Git. 二 ...