Increasing Subsequence —— 1I
Increasing Subsequence
题目描述
给出排列P,两个人轮流取数,每次取的数需要在之前该人取数的右边,且比当前取出来所有的数都要大。所有当前可选的数都将等概率随机的被当前决策人选中。问两个人期望取数的轮数。
范围
题解
概率dp,设表示第一个人上一步选了,第二个人选了,当前的答案。
注意到计算时可以使用前缀和优化,复杂度
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
const int mod = 998244353;
#define ll long long
int pow_mod(int a,int b) {
int res = 1;
while(b) {
if(b & 1) res = 1ll * res * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return res % mod;
}
ll f[N][N];
ll sum[N];
int inv[N];
int a[N];
ll cnt[N];
int main () {
int n;
cin >> n;
for(int i = 1;i <= n; ++i) {
cin >> a[i];
}
for(int i = 1;i <= n; ++i) {
inv[i] = pow_mod(i,mod - 2);
}
for(int i = n;i >= 1; --i) {
ll s = 0;
ll c = 0;
for(int j = n;j >= 0; --j) {
if(i == j) continue;
if(a[i] > a[j]) {
f[i][j] = (1 + s * inv[c]) % mod;
sum[j] = (sum[j] + f[i][j]) % mod;
cnt[j] ++;
}
else {
f[i][j] = (1 + sum[j] * inv[cnt[j]]) % mod;
s = (s + f[i][j]) % mod;
c ++;
}
}
}
ll ans = 0;
for(int i = 1;i <= n; ++i) {
ans = (ans + f[i][0]) % mod;
}
cout << 1ll * ans * inv[n] % mod << endl;
return 0;
}
分类:
动态规划
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
· 重磅发布!DeepSeek 微调秘籍揭秘,一键解锁升级版全家桶,AI 玩家必备神器!