专栏文章

题解:P11998 哇,这就是 5p

P11998题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mippv8k7
此快照首次捕获于
2025/12/03 15:59
3 个月前
此快照最后确认于
2025/12/03 15:59
3 个月前
查看原文
首先我们可以发现时限两秒,也就是说明 O(nm)O(nm) 可以通过去,这就为我们实现动态规划这个算法奠定了基础 当然应该有比这个时间复杂度更快的做法
我们不妨设计一个状态 dpi,jdp_{i,j},用来表示做到第 ii 道题时,此时的分数除以 mm 的余数为 jj 的概率为多少。
那此时此刻对于第 ii 道题有两种选择:
  • 假如这题做对了,那 dpi,jdp_{i,j} 需要加上 dpi1,(jai+m)modm×pimodmoddp_{i-1,(j-a_{i}+m) \mod m} \times p_{i} \mod mod
  • 假如这题没做对,那 dpi,jdp_{i,j} 需要加上 dpi1,j×(1pi+mod)modmoddp_{i-1,j} \times (1-p_{i}+mod) \mod mod
所以动态转移方程就是 dpi,j=(dpi1,(jai+m)modm×pi+dpi1,j×(1pi+mod)modmod)modmoddp_{i,j} = (dp_{i-1,(j-a_{i}+m) \mod m} \times p_{i} + dp_{i-1,j} \times (1-p_{i}+mod) \mod mod) \mod modmodmod998244853998244853
注:(1pi+mod)modmod(1-p_{i}+mod) \mod mod 用来表示 1pimodmod1-p_{i} \mod mod 的结果,就是没做对的概率。以下为推理过程:
  • 题目已经说了 pip_{i} 一定能够被表示成 ab\frac{a}{b} 的形式,且 b<998244853b < 998244853,再根据题目说的有理数取余,则 ab=a×bmod2\frac{a}{b} = a \times b^{mod-2}。现令 mod2mod-2AA,则 1pi1-p_{i} 可表示为 bab\frac{b-a}{b},所以 1pimodmod1-p_{i} \mod mod 的结果为 bA+1a×bAb^{A+1} - a \times b^A,根据 费马小定理bA+1b^{A+1} 在模 modmod 的情况下就为 11,而 a×bAa \times b^A 在模 modmod 的情况下就为 pip_{i},在代入回去就可以得到了。
但是这样子数组的空间可能会爆掉,但我们可以发现一个状态的转移只会依赖上一个状态的结果,所以我们就可以用滚动数组来优化。
代码部分:
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1,mod=998244853;
int n,m,a[N],p[N],tot,dp[2][1001];
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]%=m;
	for(int i=1;i<=n;i++) scanf("%lld",&p[i]);
	dp[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		int tott=tot^1;
		memset(dp[tott],0,sizeof(dp[tott]));
		for(int j=0;j<m;j++)
		{
			dp[tott][j]+=dp[tot][j]*((1-p[i]+mod)%mod)%mod,dp[tott][j]%=mod;
			dp[tott][j]+=dp[tot][(j-a[i]+m)%m]*p[i]%mod,dp[tott][j]%=mod;
		}
		tot=tott;
	}
	printf("%lld",dp[tot][0]);
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...