Atcoder ARC112 Cigar Box
这可能是我目前做到的最猛的魔法 之一了。
首先我们不妨先假设我们已经得到了一个操作序列。
因此,我们可以定义对某一个元素的最后一次移动,我们称它为该元素的关键操作。
我们不妨假设我们已经对某两个元素完成了关键操作。
则在当前序列中不在这两个元素之间的元素不能够成为这两个元素之间的元素,换句话说这两个元素间的元素若在目标序列中也在这两个元素之间则他们必然已经完成了他们的关键操作,或者他们完全不用操作。
因此我们得到了结论一:完成关键操作的元素在目标序列中是连续的。
我们考虑那些完全不用操作的元素可能在哪些位置。
我们不妨考虑第一个完成向左的关键操作的元素,则在目标序列中在该元素左边的元素必然需要操作。
第一个完成向右的关键操作的元素同理。
则最后我们发现在第一个完成向左的关键操作的元素和第一个向右的之间的元素是不用操作的。则在目标序列中,这些元素相对位置和原序列中一样,即这些元素单调递增。
我们不妨枚举目标序列中间的一段元素单调递增的区间,由性质一可以得到区间左边这些元素发生关键操作顺序和右边发生关键操作顺序,因此我们可以采用 处理。
定义 表示进行 个操作后,在目标序列所选定的区间左边的元素中还有 个没有发生关键操作,右边还有 个没有发生关键操作。
则有转移方程:
答案是 。
于是我们得到了 的优秀做法。
我们发现我们每次 的转移类似,我们考虑一次性 预处理出所以可能用到的值。
因此类似的,我们可以定义 在目标序列所选定的区间左边的元素中还有 个没有发生关键操作,右边还有 个没有发生关键操作的一种序列变成 , 在 次内变成目标序列的方案数。
这次我们考虑倒序还原。
我们考虑当前的情况是如何得到的,考虑正序时这一步不是任何一个元素的关键操作,则得到这样一个情况我们上一步有 个选择。
若正序时这一步是关键操作,则正序时这一步到当前只有唯一一种方式。
则有方程:
对于这个方程我们可以理解为上一个序列是已经确定的,当前这一序列是不确定的,但无论当前长什么样,推到目标序列步数都是一样的,所以不影响。
于是我们得到了 的优秀算法。
考虑继续优化,我们发现第二个转移方程和第三个相似,我们不妨将后两维其压缩得到 。转移类似,我们考虑但是实际上, 计算值是只考虑了发生关键操作与否的顺序,而没有考虑左右关键操作的顺序,因此需要额外计算,于是有 。
最后我们得到了 的优秀算法,满足题目要求。
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL mod = 998244353;
LL dp[3005][3005] , n , m , a[3005] , C[3005][3005];
void Add(LL &x , LL y) {x = (x + y) % mod;}
int main() {
scanf("%lld %lld" , &n , &m);
for (int i = 1; i <= n; ++i) scanf("%lld" , &a[i]);
C[0][0] = 1;
for (int i = 1; i <= n; ++i) {
C[i][0] = 1;
for (int j = 1; j <= i; ++j) {
Add(C[i][j] , C[i - 1][j - 1]);
Add(C[i][j] , C[i - 1][j]);
}
}
dp[0][0] = 1;
for (int i = 0; i < m; ++i) {
for (int j = 0; j <= n; ++j) {
Add(dp[i + 1][j] , dp[i][j] * j * 2ll % mod);
Add(dp[i + 1][j + 1] , dp[i][j]);
}
}
LL ans = 0;
for (int l = 0; l <= n; ++l) {
for (int r = n - l; r >= 0; --r) {
if(n - l - r >= 2 && a[n - r - 1] > a[n - r]) break;
Add(ans , dp[m][l + r] * C[l + r][l] % mod);
}
}
printf("%lld" , ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)