首页 > 其他分享 >AtCoder Beginner Contest 382-E

AtCoder Beginner Contest 382-E

时间:2024-12-01 11:56:32浏览次数:9  
标签:AtCoder Beginner 开包 align 稀有 卡牌 leq 382 dp

Problem

有无数包牌,每包有 \(N\) 张牌。在每一包牌中, 第 \(i\) 张牌是稀有牌,概率为 \(P_i\%\)。每张牌是否稀有与其他牌是否稀有无关。

逐一打开包装,并获得每包中的所有卡片。当你一直开包直到总共获得至少 \(X\) 张稀有卡牌时,求你开包的预期次数。

Constraints

\(1 \leq N \leq 5000,1 \leq X \leq 5000,1 \leq P_i \leq 100\)

Solution

该问题可以分为两个部分。

首先,求出开一包卡牌将会得到的稀有卡牌数量的分布列

这是一个多元二项分布问题,直接暴力计算的话需要枚举一包卡牌的子集。

考虑动态规划。设 \(dp_{i,j}\) 为一包卡牌内前 \(i\) 张牌中存在 \(j\) 张稀有牌的概率。\(dp_{i,j}\) 可由两个状态转移:原本抽到了 \(j-1\) 张稀有牌,再翻一张发现正好是稀有牌;原本抽到了 \(j\) 张稀有牌,再翻一张发现不是稀有牌。故转移方程为:

\[\begin{align} dp_{i,j}=dp_{i-1,j-1}\times \frac{P_i}{100}+dp_{i-1,j}\times\frac{(1-P_i)}{100} \end{align} \]

其中,\(dp_{0,0}=1,dp_{i,j}=0(j<0)\)。

通过上述动态规划得到 \(P(开一包卡牌得到j张稀有卡牌)=dp_{n,j}\),将其记作 \(Y_j\)。

接着解决第二个问题:已知开一包卡牌得到的稀有卡牌数量分布列为 \(Y_j\),求开出 \(X\) 张稀有牌的期望开包次数

设得到 \(i\) 张稀有牌的期望开包次数是 \(E_i\)。对于 \(i=0\),有 \(E_i=0\)。模拟一次开包,将会有 \(Y_j\) 的概率获得 \(j\) 张稀有牌。所以有:

\[\begin{align} E_i=1+\sum_{j=0}^nE_{\max(i-j,0)}\cdot Y_j \end{align} \]

但是这个方程左右两侧都有 \(E_i\) 项(\(j=0\) 时),所以不能简单的递推。

将式子变换一下:

\[\begin{align} E_i&=1+E_i\cdot Y_0+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j\\ E_i\times(1-Y_0)&=1+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j\\ E_i&=\frac{1+\sum_{j=1}^nE_{\max(i-j,0)}\cdot Y_j}{(1-Y_0)} \end{align} \]

Code

#define N 6010

int n,m;
double p[N];
double dp[N][N];
double E[N];
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>p[i],p[i]/=100;
	dp[0][0]=1; //起始条件,抽前0张牌的时候得到0张稀有牌的概率是100%
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=i;j++)
		{
			//抽前i张卡牌,正好得到j张稀有牌的概率是dp[i][j]
			if(j==0) dp[i][j]=dp[i-1][j]*(1-p[i]); //防止越界
			else dp[i][j]=dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i]);
		}
	}
	//此时得到了开一次包的概率分布表(得到j张稀有牌)为dp[n][j]
	for(int j=0;j<=n;j++)
	{
//		DEBUG(j,1);
//		DEBUG(dp[n][j],2);
	}
	for(int i=1;i<=m;i++)
	{
		//得到i张稀有牌的期望开包次数是E[i]
		for(int j=1;j<=n;j++)
		{
			if(i-j>=0) E[i]+=(E[i-j])*dp[n][j];
			else E[i]+=(0)*dp[n][j];
		}
		E[i]=(1+E[i])/(1-dp[n][0]);
	}
	cout<<E[m]<<endl;
}

标签:AtCoder,Beginner,开包,align,稀有,卡牌,leq,382,dp
From: https://www.cnblogs.com/Vanilla-chan/p/18579643

相关文章

  • AtCoder Beginner Contest 382 Solution
    A-DailyCookie(abc382A)题目大意给定一个长度为N的字符串,有很多.和@,一共有D天,每天会使一个@变成.,问D天之后有几个.解题思路数一下有几个.,答案会加D个.。代码voidsolve(){intn,d;strings;cin>>n>>d>>s;cout<<count(s.begin(),s.end(),'.......
  • AtCoder Beginner Contest 380 Solution
    A-1232336个数问是不是1个1,2个2,3个3#include<bits/stdc++.h>usingnamespacestd;inta[4];intmain(){strings;cin>>s;for(inti=0;i<s.size();i++)a[s[i]-'0']++;if(a[1]==1&&a[2]==2......
  • ABC382
    上午NOIP太憋屈了,我要切水恢复一下信心(希望cy别看见A-DailyCookie在题目限制中,已经确定\(S\)中@字符的个数多于\(D\)。所以我们直接数.的个数加上\(D\)就可以。时间复杂度\(O(n)\)。点击查看代码#include<iostream>#include<cstdio>usingnamespace......
  • AtCoder Beginner Contest 382 赛后复盘
    abc381的赛后总结不见了。(人话:没写)A-B模拟即可C因为好吃的会被前面的人吃掉,后面的人只能捡垃圾吃,所以实际上能吃东西的\(a\)成单调递减。所以我们直接二分在哪个区间即可,时间复杂度\(O(m\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#de......
  • AtCoder Beginner Contest 382
    A-DailyCookie题意给定长为\(n\)的串,“.”代表空,“@”代表饼干,一天吃一块饼干,问\(d\)天后有几个格子是空的。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e......
  • Atcoder Beginner Contest 330 题解
    前言过于水的一场。ACountingPasses题面给出一个长度为\(n\)的序列\(a\),求出\(a\)之中大于等于\(l\)的数个个数。\(1\len\le100,1\lea_i\le1000,1\lel\le1000\)。制約入力は全て整数$1\\le\N\\le\100$$1\\le\L\\le\1000$$0\\le\A_i\\le......
  • AtCoder Beginner Contest 381
    省流版A.按题意判断即可B.按题意判断即可C.枚举/的位置,然后分别向左右找到最长的1串和2串,然后取最小值即可D.讨论起始位置的奇偶性,然后用双指针,每两个字符每两个字符,维护出现的次数为2,两种情况取最大值即可E.答案为所有/的左右12个数的最小值的最大值,注意到个数随着/......
  • AtCoder ABC321F - #(subset sum = K) with Add and Erase 题解 可撤销背包
    题目链接:https://atcoder.jp/contests/abc321/tasks/abc321_f题目大意:给定大小为\(k\)的背包和\(q\)次操作,支持两种操作:插入一个大小为\(x\)的元素;删除一个大小为\(x\)的元素。每次操作后,求装满背包方案数。解题思路:可撤销背包。插入\(x\)时,fori=K->x......
  • Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)
    A-Cyclic链接:A-Cyclic代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ stringss; cin>>ss; cout<<ss[1]<<ss[2]<<ss[0]<<""<<ss[2]<<ss[0]<<ss[1]; return0;}B-Strawberri......
  • 【Atcoder训练记录】AtCoder Beginner Contest 381
    训练情况赛后反思简单题A题做红温了,怒吃6罚时,C题双指针其实差不多想出来了,但是对于判断字符串合法其实可以只判断两个端点,不需要全部遍历,中途还想了二分做法(?),然而写到最后发现并没有二分单调性。A题记得判断字符串的长度必须是奇数,\(1\sim\frac{n+1}{2}-1\)是1,\(\frac{......