uoj311 【UNR #2】积劳成疾
【题解】
这题的期望dp好神奇啊(可能是我太菜了)
由于每个位置都完全一样,所以我们设fi,j表示审了连续i个位置,最大值不超过j的期望。
那么只要考虑最大值为j的期望,其他从f_{i,j-1}加进来即可。
枚举最大值第一次出现的位置p(如果位置编号为[1,i]的话,因为位置都等价,所以可以这样做)
然后考虑p一定对于这些区间有贡献[\max(1, p-K+1), \min(i-K+1, p)],那么这些区间的价值都是w_j,乘起来即可。
然后前后两半互斥,分别转移即可。
设区间长度为len,也就是上面那坨减一下+1。
所以f_{i,j} = f_{i,j-1} + \sum_{p=1}^i f_{p-1,j-1} * w_j^{len} * f_{i-p, j}
考虑初始状态,连续i个位置最大值不超过j,其中i < k,也就是还没有组成一个完整的区间,那么根据上面的转移方程,这个区间的值完全由自己决定,也就是f_{i,j} = j^i。
复杂度O(n^3)
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 410 + 10; const int mod = 998244353; int n, K, w[M]; int f[M][M], c[M][M]; // 审了i套题,最大难度不超过j的方案数 // f[i, j] = f[i, j-1] + \sum_{x=1}^{i} f[x-1, j-1] * f[n-x, j] * w[x]^p inline int pwr(int a, int b) { int ret = 1; while(b) { if(b&1) ret = 1ll * ret * a % mod; a = 1ll * a * a % mod; b >>= 1; } return ret; } int main() { cin >> n >> K; for (int i=1; i<=n; ++i) { scanf("%d", w+i); c[i][0] = 1; for (int j=1; j<=n; ++j) c[i][j] = 1ll * c[i][j-1] * w[i] % mod; } for (int i=0; i<=n; ++i) f[0][i] = 1; for (int i=1; i<=n; ++i) { for (int j=1; j<=n; ++j) { if(i < K) f[i][j] = pwr(j, i); else { f[i][j] = f[i][j-1]; for (int x=1; x<=i; ++x) { f[i][j] = f[i][j] + 1ll * f[x-1][j-1] * f[i-x][j] % mod * c[j][min(i-K+1, x) - max(x-K+1, 1) + 1] % mod; if(f[i][j] >= mod) f[i][j] -= mod; } } } } cout << f[n][n]; return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用