Codeforces908D. New Year and Arbitrary Arrangement【期望dp】

题目大意:

给定整数k,pa,pb。
初始有一个空序列,每次往末尾添加一个字符,有pa/(pa+pb)的概率添加a,有pb/(pa+pb)的概率添加b。
当ab作为子序列出现了至少k次的时候停止,问此时ab子序列出现次数的期望。对10^9+7取模。
1<=k<=1000,1<=pa,pb<=10^6。

解题思路:

f [ i ] [ j ] f[i][j] f[i][j]表示当前有 i i i 个a, j j j 个ab子序列到停止时的期望,那么
f [ i ] [ j ] = p a p a + p b f [ i + 1 ] [ j ] + p b p a + p b f [ i ] [ j + i ] f[i][j]=\frac{pa}{pa+pb}f[i+1][j]+\frac{pb}{pa+pb}f[i][j+i] f[i][j]=pa+pbpaf[i+1][j]+pa+pbpbf[i][j+i]

其实以上都不是重点,重点在于定下目标状态和终止状态值。

1.目标状态:
如果我们把目标状态定为 f [ 0 ] [ 0 ] f[0][0] f[0][0],那么
f [ 0 ] [ 0 ] = ( p a ∗ f [ 1 ] [ 0 ] + p b ∗ f [ 0 ] [ 0 ] ) / ( p a + p b ) f[0][0]=(pa*f[1][0]+pb*f[0][0])/(pa+pb) f[0][0]=(paf[1][0]+pbf[0][0])/(pa+pb)会死循环,相当于一开始会有无穷多个b:bbbbb…….bbbbaababa…
但也可推出 f [ 0 ] [ 0 ] = f [ 1 ] [ 0 ] f[0][0]=f[1][0] f[0][0]=f[1][0],所以目标状态应为 f [ 1 ] [ 0 ] f[1][0] f[1][0]

2.终止状态:
i + j ≥ k i+j\ge k i+jk 时,再出现一个b就会停止,所以当 i + j ≥ k i+j\ge k i+jk
f [ i ] [ j ] = ( i + j ) B + ( i + j + 1 ) A B + ( i + j + 2 ) A 2 B + . . . f[i][j]=(i+j)B+(i+j+1)AB+(i+j+2)A^2B+... f[i][j]=(i+j)B+(i+j+1)AB+(i+j+2)A2B+...用差比数列的方法计算可得 f [ i ] [ j ] = i + j + p a p b f[i][j]=i+j+\frac{pa}{pb} f[i][j]=i+j+pbpa

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
    int i=0,f=1;char c;
    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
    if(c=='-')c=getchar(),f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}
const int N=1005,mod=1e9+7;
int k;ll pa,pb,inv_pb,f[N][N];
ll Pow(ll x,int y)
{
	ll res=1;
	for(;y;y>>=1,x=x*x%mod)
		if(y&1)res=res*x%mod;
	return res;
}
ll dfs(int i,int j)
{
	if(i+j>=k)return (i+j+pa*inv_pb)%mod;
	if(f[i][j]!=-1)return f[i][j];
	return f[i][j]=(dfs(i+1,j)*pa+dfs(i,j+i)*pb)%mod;
}
int main()
{
	//freopen("lx.in","r",stdin);
	memset(f,-1,sizeof(f));
	k=getint(),pa=getint(),pb=getint();
	pa=pa*Pow(pa+pb,mod-2)%mod,pb=(1-pa+mod)%mod,inv_pb=Pow(pb,mod-2);
	printf("%lld\n",dfs(1,0));
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。Gym是Codeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值