牛牛和数组操作

  • description
  • solution
  • code

description

【题目描述】
有n + 2个整数a0, a1, . . . , an, an+1, a0 = an+1 = 0。你需要做确切地n次操作,每次
操作为以下形式:
选择一个整数x满足ax ≠ 0,使得ax = 0,令l=maxi<x,ai=0(i),r=mini>x,ai=0(i)l=\text{max}_{i<x,a_i=0}(i),r=\text{min}_{i>x,a_i=0}(i)l=maxi<x,ai​=0​(i),r=mini>x,ai​=0​(i),此次操
作的花费为max(al, al+1+, . . . , ax-1) + max(ax+1. . . , ar-1, ar)牛币。
有多少不同的操作方式使得操作花费的牛币最少,两种操作不同当且仅当两种操
作的操作序列不同。
答案对998244353取模。
友情提示:本题正解复杂度很大,常数很小。
【输入格式】
第一行一个整数n。
第二行n个整数a1, a2, . . . , an。
【输出格式】
输出一行一个整数表示答案。
【样例 1 输入】
5
2 2 2 1 1
【样例 1 输出】
40
【样例 2 输入】
88
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3
4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1
2 3
【样例 2 输出】
235381964
【数据范围】

1≤n≤2000,1≤ai≤n1\le n\le 2000, 1\le a_i\le n1≤n≤2000,1≤ai​≤n

solution

设第一个操作的人编号为xxx,则在xxx被操作后,[1,x−1][1,x-1][1,x−1]和[x+1,n][x+1,n][x+1,n]的区间操作就互不影响了

因此可以考虑区间dpdpdp

设fl,rf_{l,r}fl,r​为对区间[l,r][l,r][l,r]操作的最小代价,gl,rg_{l,r}gl,r​为对区间[l,r][l,r][l,r]操作最小代价的不同操作序列数量

枚举区间操作点iii,则fl,r=min{fl,i−1+fi+1,r},gl,r=gl,i−1∗gi+1,r∗(r−li−l)f_{l,r}=\text{min}\{f_{l,i-1}+f_{i+1,r}\},g_{l,r}=g_{l,i-1}*g_{i+1,r}*\binom{r-l}{i-l}fl,r​=min{fl,i−1​+fi+1,r​},gl,r​=gl,i−1​∗gi+1,r​∗(i−lr−l​)

虽然区间dpdpdp是从小到大,但实际上我们的操作是将大区间操作某个点切割成若干小区间

到这里为止,时间复杂度就是O(n3)O(n^3)O(n3),但是评测机上面跑得飞快,就人间迷惑行为??

以下是不清楚题解的“正解” :实际上,贪心的想法,操作区间的最大值肯定是最优秀的,因此只需要枚举区间最大值即可。同时对于一段区间[l,r][l,r][l,r],如果存在ai=ai+1=max(aj,j∈[l,r))a_i=a_{i+1}=\text{max}\Big(a_j,j\in[l,r)\Big)ai​=ai+1​=max(aj​,j∈[l,r))则此时i,i+1i,i+1i,i+1的选择顺序没有影响,因此当碰到连续两个最大值出现时,直接将区间划分为两段,最大值不连续则仍直接枚举最大值,从而时间复杂度为O(n32)O(n^{\frac{3}{2}})O(n23​)

code

#include <cstdio>
#include <iostream>
using namespace std;
#define int long long
#define mod 998244353
#define maxn 2005
int c[maxn][maxn], f[maxn][maxn], g[maxn][maxn], Max[maxn][maxn];
int a[maxn];
int n;signed main() {freopen( "array.in", "r", stdin );freopen( "array.out", "w", stdout );scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );for( int i = 0;i <= n;i ++ ) {c[i][0] = c[i][i] = 1;for( int j = 1;j < i;j ++ )c[i][j] = ( c[i - 1][j - 1] + c[i - 1][j] ) % mod;}g[n + 1][n] = 1;for( int l = n;l;l -- ) {g[l][l] = g[l][l - 1] = 1, Max[l][l] = a[l];for( int r = l + 1;r <= n;r ++ ) {f[l][r] = 1e18;Max[l][r] = max( Max[l][r - 1], a[r] );for( int i = l;i <= r;i ++ ) {int x = Max[l][i - 1] + Max[i + 1][r] + f[l][i - 1] + f[i + 1][r];int cnt = g[l][i - 1] * g[i + 1][r] % mod * c[r - l][i - l] % mod;if( x < f[l][r] ) f[l][r] = x, g[l][r] = cnt;else if( x == f[l][r] ) g[l][r] = ( g[l][r] + cnt ) % mod;}}}printf( "%lld\n", g[1][n] );return 0;
}

2021牛客NOIP提高组OI赛前模拟赛第一场T2——牛牛和数组操作(区间dp)相关推荐

  1. 牛客NOIP2021提高组OI赛前模拟赛第一场T3——与巨(数学)

    与巨 description solution code description [题目描述] 定义无穷序列f:f1=1,fn=fn−1∗2+1f:f_1=1,f_n=f_{n-1}*2+1f:f1​ ...

  2. 2021牛客NOIP提高组第二场T2——方格计数(组合数计数)

    方格计数 description solution code description 在左下角是 (

  3. 牛客网暑期ACM多校训练营(第一场)

    牛客网暑期ACM多校训练营(第一场) A. Monotonic Matrix 考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着 ...

  4. [牛客][NOIP2000提高组]乘积最大(Java)(动态规划+高精度)

    原题链接:乘积最大 链接:https://ac.nowcoder.com/acm/problem/16757 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144 ...

  5. 牛客网暑期ACM多校训练营(第二场): H. travel(树形线头DP)

    链接:https://ac.nowcoder.com/acm/contest/140/H 来源:牛客网 题目描述 White Cloud has a tree with n nodes.The roo ...

  6. [2019 牛客CSP-S提高组赛前集训营4题解] 复读数组(数论)+ 路径计数机(数上DP)+ 排列计数机(线段树+二项式定理)

    文章目录 T1:复读数组 题目 题解 代码实现 T2:路径计数机 题目 题解 代码实现 T3:排列计数机 题目 题解 CODE T1:复读数组 题目 有一个长为n×k的数组,它是由长为n的数组A1,A ...

  7. [NowCoder牛客]2021NOIP提高组模拟赛第二场T3——树数树(启发式合并堆)

    树数树 description solution code description [题目描述] 牛牛有一棵 n 个点的有根树,根为 1. 我们称一个长度为 m 的序列 a 是好的,当且仅当: • ∀

  8. 牛客网提高组模拟赛第七场 T3 洞穴(附bitset介绍)

    就是DP. 我们可以很简单的想到要枚举中间点,进行边数的转移. 但是因为边长数据范围很大,所以我们考虑log的倍增. 状态设计为\(dp[i][j][k]\),为从节点\(i\)走\(2^k\)步能否 ...

  9. 【2020.10.17 牛客 普及组 模拟赛一】T2 牛牛的跳跳棋

    题目描述 牛牛最近在玩一种叫做跳跳棋的游戏,棋盘可以看成是一个一维的线性数组,编号从1到n+1n+1n+1. 一开始牛牛的棋子位于第1个格子,游戏的最终目的是将棋子移动到第n+1n+1n+1个格子. ...

最新文章

  1. visio 模具_小研爱科研 || 那些Visio里的小技巧你Get了吗?
  2. android 前台服务自定义布局不显示_Android自定义LinearLayout布局显示不完整的解决方法...
  3. 数据结构与算法--复杂链表的复制
  4. HSSFCellStyle.ALIGN_CENTER报错
  5. 计算机一级excel如何选择2个,2017年计算机一级excel操作题(2)
  6. Stack View的与众不同
  7. comps电磁场模拟软件_电气工程仿真
  8. CnPack源码模板功能快速添加注释
  9. 穿透还原卡和还原软件的代码
  10. PDF转CAD工具怎么选择
  11. 【ROS】header.stamp与double转换
  12. 大寰机器人通讯转换系统(CTS-B1.0) 操作说明
  13. 【云原生 | 13】手把手教你搭建ferry开源工单系统
  14. wz的作战演习计划--分治思想
  15. 神经网络 mse一直不变_用深层神经网络解释大脑的运作
  16. 东南亚(Lazada shoppe)自养号测评如何解决收货地址及ip问题详解
  17. 3-6岁经典绘本分级大推荐,给孩子先收藏起来
  18. Linux下安装nginx1.8+php7+mysql57
  19. jt808/jt1078
  20. C++:94---类继承(菱形继承、虚继承(virtual虚基类))

热门文章

  1. R语言和 Python —— 一个错误的分裂
  2. 这是一份编程宝典,请查收!
  3. 主成分分析和因子分析十大不同点
  4. java 上传文件编码_(java)有什么办法把MultipartFile上传的文件转为utf-8的编码吗
  5. 用wxpython做ui_wxPython - 如何强制UI刷新?
  6. Java千万数据导入mysql_java之5分钟插入千万条数据
  7. 判断小数是否相等_五年级上册数学综合练习题(填空、判断、选择、文字题),覆盖全册知识点!...
  8. php获取域名方法,PHP实现获取域名的方法小结
  9. c语言综合模拟测试题答案,【C语言指针模拟测试题_答案】
  10. eclipse 输入卡顿_7个小技巧,解决eclipse卡顿问题