【hiho挑战赛24 A&B&C】贪心和期望dp惨烈的后缀自动机

本文详细解析了一道涉及概率论与子序列计数的算法题。通过递推公式和前缀和优化技巧,实现了O(n)的时间复杂度。文章给出了清晰的解题思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A题目传送门
B题目传送门
C题目传送门

A


因为太水,我不想写题解,Yvehの传送门

B


思路:
很强的一道题目(聪哥说是概率入门题……)
昨天打比赛时懵逼了很久
我们先考虑一个简单的问题,如果 a[i]=0 ,怎么做?
一道比较经典的题目(51nod 1202),给定序列 s ,求不同的子序列个数
f[i]表示到第 i 位时本质不同的子序列的个数,对于第i位来说有选和不选两种可能,那么方程就是

f[i]=f[i1]×2

但这是在 s[i] 没有出现过的情况下的方程
那如果 s[i] 之前已经出现过呢?
s[i] 最后出现的位置是 last ,那么方程就是

f[i]=f[i1]×2f[last1]

我们可以这么想,这时重复的串就是last之前的子序列分别与 s[last] , s[i] 相匹配,这些子序列的数量就是 f[last1]
这样就可以在 O(n) 时间内递推出 f[n]
但是这里加入了概率,我们怎么在这上面改进呢?
我先给出方程,下面再解释
a[i] 表示第i位被删除的概率, f[i] 表示到第 i 位时本质不同的子序列的期望,sum[i]表示 i 本身及i所有可能的 last 的前一位的期望的前缀和
咦,好像 sum[i] 的定义很诡异啊,我们来重新断下句(。・∀・)ノ゙
sum[i] 表示
i 本身及i所有可能的 last
的前一位
的期望
的前缀和
如果没看懂就继续往下看好了= =
f[i]=(f[i1]×2sum[last])×(1a[i])+f[i1]×a[i]

sum[i]=f[i1]×(1a[i])+sum[last]×a[i]

考虑第 i 位时,如果第i位被删除了,那么第 i 位的的期望就是前一位的期望(即f[i1]),如果没被删除,那么就可以仿照 a[i]=0 时的情况了,但这时我们发现,last的位置并不是固定的,而是有多种可能的,在这里,朴素的想法是枚举所有可能的 last ,然后累加它们的不被删除时前一位的 f ,得出答案,但这个转移最坏情况下是O(n)的,所以考虑前缀和优化, sum[i] 就是做这个用的
sum[i] 的求法也很简单,类似 f[i] ,如果 i 没被删除,那就是f[i1],反之就是 sum[last]
乘下相应的概率就可以了
由于要取模,所以先求下 100 关于 998244353 的逆元
时间复杂度和空间复杂度都是 O(n)
代码:

#include<cstdio>
#include<iostream>
#define M 500003 
#define mo 998244353
#define LL long long
using namespace std;
int n;
char s[M];
int a[M],last[27],f[M],sum[M];
int qr(int x,int y)
{
    int t=1;
    for (;y;y>>=1,x=(LL)x*x%mo)
        if (y&1) t=(LL)t*x%mo;
    return t;
}
main()
{
    scanf("%d",&n);
    scanf("%s",s+1);
    for (int i=1;i<=n;++i) scanf("%d",a+i);
    int inv=qr(100,mo-2);
    f[0]=1;
    for (int i=1;i<=n;++i)
    {
        int t=sum[last[s[i]-'a']];
        f[i]=((100-a[i])*(2LL*f[i-1]%mo-t)%mo+(LL)a[i]*f[i-1]%mo)%mo*inv%mo;
        sum[i]=((LL)f[i-1]*(100-a[i])%mo+(LL)t*a[i]%mo)*inv%mo;
        last[s[i]-'a']=i;
    }
    printf("%d\n",(f[n]+mo)%mo);
}

C


因为太神太麻烦不想写题解了
Yvehの传送门

有没有被骗到啊(。・∀・)ノ

B题写这么详细已经很良心的啦QAQ

1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值