当前位置: 首页 > news >正文

CF2144E1 思路分享(dp)

https://codeforces.com/problemset/problem/2144/E1

题意概述

\(n\) 座塔从左到右排列,高度为 \(a_i\),记 \(L(a)\) 为从左看依次能看见的塔的高度,\(R(a)\) 为从右看依次能看见的塔的高度,求满足 \(L(a)=L(a')\)\(R(a)=R(a')\)\(a'\) 数量,其中 \(a'\)\(a\) 的子序列,模 \(998244353\).

\(1\le n \le 5000\).

思路

只考虑左边,考虑 \(dp\),记 \(dp1[i][j]\)\(a\) 中前 \(i\) 个元素能匹配 \(L(a)\) 的前 \(j\) 个元素的方案数,讨论每个位置选或不选转移即可.

类似地处理右边,记为 \(dp2\).

考虑如何整合,发现只需关注最大值位置,枚举左边最大值第一次出现位置 \(p\) 和右边最大值第一次出现位置 \(q\),将两边方案数相乘,中间数任选.

为了刻画最大值第一次出现,需要一些处理,记 \(len=|idx|\)\(m_1=|L(a)|\)\(m_2=|R(a)|\), 具体地,总贡献为:

\[\sum_{i=0}^{len}{\sum_{j=i}^{len}{dp1[idx[i]-1][m_1-1] \cdot dp2[idx[j]+1][m_2-1] \cdot 2^{\max(0,idx[j]-idx[i]-1)}}} \]

时间复杂度 \(\mathcal{O}(n^2)\).

代码

//author:kzssCCC#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int MOD = 998244353;
const int INF = 1e9;ll qpow(ll a,ll b){ll res = 1;while (b){if (b&1){res = res*a%MOD;}a = a*a%MOD;b >>= 1;}return res;
}void solve(){int n;cin >> n;vector<int> a(n+1);for (int i=1;i<=n;i++){cin >> a[i];}int pre = 0;vector<int> temp{0};for (int i=1;i<=n;i++){pre = max(pre,a[i]);temp.push_back(pre);}sort(temp.begin()+1,temp.end());temp.erase(unique(temp.begin()+1,temp.end()),temp.end());int m = temp.size()-1;vector<vector<ll>> dp(n+1,vector<ll>(m+1));dp[0][0] = 1;for (int i=1;i<=n;i++){dp[i] = dp[i-1];for (int j=0;j<=m;j++){if (a[i]<=temp[j]){dp[i][j] = (dp[i][j]+dp[i-1][j])%MOD;}else if (j+1<=m && a[i]==temp[j+1]){dp[i][j+1] = (dp[i][j+1]+dp[i-1][j])%MOD;}}} int suf = 0;temp.clear();temp.push_back(0);for (int i=n;i>=1;i--){suf = max(suf,a[i]);temp.push_back(suf);}sort(temp.begin()+1,temp.end());temp.erase(unique(temp.begin()+1,temp.end()),temp.end());int m2 = temp.size()-1;vector<vector<ll>> dp2(n+2,vector<ll>(m2+1));dp2[n+1][0] = 1;for (int i=n;i>=1;i--){dp2[i] = dp2[i+1];for (int j=0;j<=m2;j++){if (a[i]<=temp[j]){dp2[i][j] = (dp2[i][j]+dp2[i+1][j])%MOD;}else if (j+1<=m2 && a[i]==temp[j+1]){dp2[i][j+1] = (dp2[i][j+1]+dp2[i+1][j])%MOD;}}}int mx = temp.back();vector<int> idx;for (int i=1;i<=n;i++){if (a[i]==mx){idx.push_back(i);}}int len = idx.size();ll res = 0;for (int i=0;i<len;i++){for (int j=i;j<len;j++){res = (res+dp[idx[i]-1][m-1]*dp2[idx[j]+1][m2-1]%MOD*qpow(2,max(0,idx[j]-idx[i]-1))%MOD)%MOD;}}cout << res << '\n';
}int main(){ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while (t--) solve();return 0;
}
http://www.gsyq.cn/news/1569610.html

相关文章:

  • 3分钟掌握Adobe-GenP:终极Adobe软件激活完整指南
  • 一篇讲清亲情账号、家庭共济与医保钱包
  • 融合GNN与LLM的平衡型游戏推荐系统:打破信息茧房
  • 一线观察:长期使用平替科思创 2655 产品的供应商实际体验
  • HSTracker:macOS炉石传说玩家的终极智能助手指南 [特殊字符]
  • 逆向工程实战:突破某天气App私有API签名加密,构建高可用Python爬虫系统
  • 年度黄金回收数据白皮书出炉,合扬凭硬核实力稳居行业龙头 - 奢侈品交易观察员
  • Maestro跨平台UI自动化测试框架:架构解析与实战对比
  • MC68HC908AT32存储系统解析:RAM、FLASH与EEPROM实战指南
  • i.MX处理器ATK定制指南:SDRAM初始化、Flash驱动与GUI扩展实战
  • 构建高效后端系统:主流技术栈选型与实践指南
  • 基于Kinetis-M MCU的高精度两相电子电能表设计解析
  • Ubuntu 20.04 安装 Jekyll 常见编译失败原因与完整构建环境配置
  • 武汉市武昌区管道疏通|维小达|马桶、蹲便器、地漏、洗菜盆、洗手盆、浴缸一站式疏通养护服务 - 维小达科技
  • Windows 7 64位下部署JDK 1.8u333实战指南
  • CentOS 8 LEMP部署:模块流、MariaDB替代与Nginx双模式详解
  • RGPO策略优化算法:基于可微拒绝门控的强化学习新范式
  • 构建可复用的iOS自动化测试技能包:基于WebDriverAgent与Python的工程实践
  • MPC5604P到MPC5643L MCU迁移指南:兼容性分析与工程实践
  • 如何在Windows上轻松安装安卓应用?APK安装器完整解决方案
  • 黄金回收扣费乱象频发?2026行业白皮书解锁合扬无套路变现 - 奢侈品交易观察员
  • 面试高频难题拆解,1000万条短信1小时推送线程池完整落地方案
  • PKHeX自动合法性插件:5分钟搞定宝可梦数据合规的终极解决方案
  • 2026年6月精冲钢厂哪家强,GCr15精冲钢/304L不锈钢/68CrNiMo精冲钢,精冲钢定制厂家实力 - 品牌推荐师
  • 3个步骤让你的macOS菜单栏焕然一新:Ice菜单栏管理终极指南
  • 5分钟掌握Unlock Music:终极音乐解密解决方案
  • 3步快速上手:B站会员购自动化抢票工具完全指南
  • 广州企业搬迁/大型家庭搬家找谁家?2026大型搬家公司车队、人员及服务能力对比一览 - 从来都是英雄出少年
  • 2026年6月重庆值得关注的音响升级门店,坦克原厂官方店上榜,原车音响升级/理想原厂音响升级,音响升级门店哪家好 - 音响改装门店分享
  • Appium Settings深度配置指南:解锁Android自动化测试系统级控制