P5131 荷取融合 —— DP
题意
有 个正整数构成的序列 ,进行如下 次操作:
- ( ) 。 然后将 加入 ( 和 均为为正整数且 初始为1, 初始为空集)。
令 ,求 的期望。
分析
观察数据范围:。
结合时限1s,我们只能接受时间复杂度为 的算法。
考虑状态设计: , 表示在 次操作后 时的权值积之和与操作方案数。
那么 由 转移而来:
由 转移而来:
记录 和 的前缀和,在处理到 , 时就可以直接计算。
再观察空间限制:125MB。
因为当前状态只由上一次选择转移而来,所以用滚动数组优化。
令 , , 。
注意取模,求逆元即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+100,K=3e2+10; const ll mod=19260817; int n,k; ll f[N][2],g[N][2],h[N]; ll qc(ll a, ll b) { ll sum=1; while(b) { if(b&1) sum=sum*a%mod; a=a*a%mod; b>>=1; } return sum; } ll ny(ll x) { return qc(x,mod-2ll); } int main() { cin>>n>>k; for(int i=1;i<=n;++i) { scanf("%lld",h+i); g[i][1]=1; f[i][1]=h[i]; } int opt=1; for(int i=2;i<=k;++i) { ll sum=0,num=0; opt^=1; for(int j=1;j<=n;++j) { sum=(sum+f[j][1-opt])%mod; num=(num+g[j][1-opt])%mod; f[j][opt]=sum*h[j]%mod; g[j][opt]=num%mod; } } ll ans1=0,ans2=0; for(int i=1;i<=n;++i) ans1=(ans1 + f[i][opt])%mod; for(int i=1;i<=n;++i) ans2=(ans2 + g[i][opt])%mod; printf("%lld",ans1*ny(ans2)%mod); return 0; }
本文来自博客园,作者:Glowingfire,转载请注明原文链接:https://www.cnblogs.com/Glowingfire/p/18673784
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程