Educational Codeforces Round 160 (Rated for Div. 2)(D 动态规划)

关于如何思考DP这件事...这题还是比较好的

思路:考虑dp[i]为当前共有 i 个数且以a_{i}为结尾,能够形成的字段的个数。要想求出dp[i]只需要知道a_{i}的前一个数可以是什么,这样就能够进行状态转移了

首先定义a_{j}a_{i}前方第一个比a_{i}小的数。

1、首先考虑比a_{i}还要大的数:如果一次操作中a_{i}是最小的话,那么就能够删掉前面的数。因此a_{i}的前一个数可以是[j + 1, i - 1]

2、接下来考虑的是比a_{i}还要小的数,可以发现a_{j}是可以被替换掉的。只需要找到a_{j}前方第一个比它小的数,那么a_{j}就会被替换掉。如此往复直到没有比它还要小的数为止。

接下来考虑如何去快速求解:

1、对于a_{i}而言,需要找到前方第一个比a_{i}还要小的数的下标,这一点可以用单调栈来实现。

2、对[j + 1, i - 1]范围内的数,可以用前缀和来快速求解。

3、对于第二种情况,它并不是连续的一些数,但是可以发现这些数都是固定的,不会随着后面的数到来而改变,因此也可以化简成一个DP,从而快速转移。

最终考虑可达数组的个数:并不是以 i 结尾就一定能构成可达数组,必须要满足a_{i}后方没有比它还要大的数才行,否则就永远不可能成为最终数组的最后一个,这个判断只需要反向整一个单调栈就行了。

// Problem: D. Array Collapse
// Contest: Codeforces - Educational Codeforces Round 160 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1913/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 998244353;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve() 
{int n;cin >> n;vector<int>dp(n + 5 , 0);vector<int>sum(n + 5 , 0);vector<int>dp2(n + 5 , 0);for(int i = 1 ; i <= n ; i ++)cin >> a[i];stack<pair<int,int>>st;vector<int>tl(n + 5 , 0);for(int i = 1 ; i <= n ; i ++){while(!st.empty()){auto tmp = st.top();if(a[i] < tmp.x){st.pop();}else{break;}}if(st.empty()){st.push({a[i] , i});tl[i] = 0;}else{auto tmp = st.top();tl[i] = tmp.y;st.push({a[i] , i});}}for(int i = 1 ; i <= n ; i ++){dp[i] = sum[i - 1] - sum[tl[i]];dp[i] += mod;if(tl[i] == 0){dp[i]++;}dp[i] += dp2[tl[i]];sum[i] = sum[i - 1] + dp[i];dp2[i] = dp2[tl[i]] + dp[i];dp[i] %= mod;sum[i] %= mod;dp2[i] %= mod;}int ans = 0;while(!st.empty()){st.pop();}for(int i = n ; i >= 1 ; i --){while(!st.empty()){auto tmp = st.top();if(a[i] < tmp.x){st.pop();}else{break;}}if(st.empty()){ans += dp[i];ans %= mod;st.push({a[i] , i});}else{st.push({a[i] , i});}}cout << ans << endl;//10//10 2///10 2 6 10 6//}            
signed main() 
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;cin>>t;while(t--){solve();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/286041.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建知识付费平台?明理信息科技为你提供全程解决方案

明理信息科技saas知识付费平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和维护…

在Java中高效使用Lambda表达式和流(Streams)的技巧

Java中如何高效使用Lambda表达式和流&#xff08;Streams&#xff09;的技巧 1. 简介 在Java中&#xff0c;Lambda表达式和流&#xff08;Streams&#xff09;是Java 8引入的两个强大的特性。Lambda表达式为Java添加了一种简洁的方式来实现函数式编程&#xff0c;而流提供了一…

为什么是60R+60R+电容,而不是直接用120R?

我们经常会在CAN通讯中看到如下所示的设计&#xff1a;CAN终端电阻不直接用120欧姆&#xff0c;而是用两个60欧姆串联&#xff0c;并且在两个电阻中间用一个小电容接地。 所以为什么这么做呢&#xff1f;难道说用一颗电阻不好吗&#xff1f;还可以节省点一些布局空间。 存在即…

【OpenGL/WebGL】Shader中如何获取摄像机视口的宽高

一、需求背景 在有些需求中&#xff0c;物体的大小是随着摄像机的视口的大小而变化的。如下图中&#xff0c;蓝色小方块&#xff0c;随着不断放大&#xff0c;其大小有个最大值&#xff0c;并不会无限放大。 这种实现的原理是在Shader中&#xff0c;不断根据摄像机近平面尺寸大…

使用kali进行抓包以及aircrack-ng跑包和hashcat跑包

文章目录 一、连接无线网卡二、抓取TCP握手包三、aircrack-ng跑包和hashcat跑包1.aircrack2.Hashcat 四、其他 环境&#xff1a; VMware Workstation 16 Pro kali-linux-2023.1 64位 python3.9.13 RT3070-USB无线网卡 一、连接无线网卡 1.首先按下winr打开运行窗口 2.输入…

JDK各个版本特性讲解-JDK9特性

JDK各个版本特性讲解-JDK9特性 一、JDK版本特性二、JDK9特性讲解1. JDK9特性概述2. JDK9的改变3. JDK和JRE目录变化4. 语法层次改变4.1 钻石操作符号语法升级4.2 try结构语法升级4.3 下划线命名标识符的使用限制 5. API层次的改变5.1 接口中的私有方法5.2 String底层存储结构变…

【SpringCloudAlibaba】Sentinel熔断限流工具的使用

一、前言 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维…

MATLAB求解微积分(代码+详细解读)

大多数实际工程问题常常简化为微分方程&#xff0c;其求解显地至关重要。 符号微积分 极限 % matlab提供的求极限函数limit(),其调用格式为 % y limit(fun,x,x0) % fun为要求解的函数&#xff0c;x为函数自变量&#xff0c;x0为函数自变量的取值&#xff0c;x趋近于x0 clc;…

STM32----HAL库函数

1.STM32系统框架 1.1 Cortex-M内核&芯片 1.2 F1系统框架 4个主动单元4个被动单元 AHB&#xff1a;高级高性能总线 APH&#xff1a;高级外围总线 其中 1 为 主动单元 &#xff0c; 2为被动单元 总线时钟频率&…

Matlab智能优化算法学习笔记(一)——粒子群算法、模拟退火算法、遗传算法、蚁群算法

文章目录 粒子群算法△ matlab工具箱粒子群函数○ 代码○○ 手搓代码实现粒子群优化 2个变量&#xff08;xy&#xff09;的粒子群优化尝试 定义函数 绘制网格图&#xff08;用来可视化过程&#xff09; 参数初始化&#xff0c;绘制粒子初始位置 开始迭代过程并绘图 获取结果并绘…

分享一个好看的vs主题

最近发现了一个很好看的vs主题&#xff08;个人认为挺好看的&#xff09;&#xff0c;想要分享给大家。 主题的名字叫NightOwl&#xff0c;和vscode的主题颜色挺像的。操作方法也十分简单&#xff0c;首先我们先在最上面哪一行找到扩展。 然后点击管理扩展&#xff0c;再搜索栏…

JMM的内存可见性保证

Java程序的 内存可见性保证 可以分为下列3类 1&#xff09;单线程程序 单线程程序不会出现内存可见性问题。 编译器、runtime、处理器会共同确保单线程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。 2&#xff09;正确同步的多线程程序 正确同步的多线程程序的…