Codeforces 908 D New Year and Arbitrary Arrangement
Discription
You are given three integers k, pa and pb.
You will construct a sequence with the following algorithm: Initially, start with the empty sequence. Each second, you do the following. With probability pa / (pa + pb), add 'a' to the end of the sequence. Otherwise (with probability pb / (pa + pb)), add 'b' to the end of the sequence.
You stop once there are at least k subsequences that form 'ab'. Determine the expected number of times 'ab' is a subsequence in the resulting sequence. It can be shown that this can be represented by P / Q, where P and Q are coprime integers, and . Print the value of
.
Input
The first line will contain three integers integer k, pa, pb (1 ≤ k ≤ 1 000, 1 ≤ pa, pb ≤ 1 000 000).
Output
Print a single integer, the answer to the problem.
Example
1 1 1
2
3 1 4
370000006
Note
The first sample, we will keep appending to our sequence until we get the subsequence 'ab' at least once. For instance, we get the sequence 'ab' with probability 1/4, 'bbab' with probability 1/16, and 'aab' with probability 1/8. Note, it's impossible for us to end with a sequence like 'aabab', since we would have stopped our algorithm once we had the prefix 'aab'.
The expected amount of times that 'ab' will occur across all valid sequences is 2.
For the second sample, the answer is equal to .
设f[i][j]为有i对ab,并且已经有j个a的期望,转移很好写,f[i][j]= (pa/(pa+pb))*f[i][j+1] + (pb/(pa+pb))*f[i+j][j] 、
但是可以发现的是如果要计算所有状态的话j显然可以无限大,,,比如全是a的序列。。。。
但是还可以发现,当i+j>=k的时候,(pb/(pa+pb))*f[i+j][j] 其实就等于 (pb/(pa+pb))*(i+j)。
这样我们等比数列错位相减一下(需要化简一大堆式子,在这就懒得写了),可以得到一个边界:f[i][j]=i+j +pa/pb (i+j>=n)
然后f[i][0]=f[i][1],这个带第一个转移的式子就可以得到。。。。。
/*
设f[i][j]为有i对ab,目前已经有了j个a的ab期望个数
1.f[i][j]= pa/pb + i+j ,其中i+j>=n (这个推个式子然后生成函数一下就OJBK了)
2.f[i][0]=f[i][1] (这个也是代换一下就好了)
3.其他情况下,f[i][j]= (pa/(pa+pb))*f[i][j+1] + (pb/(pa+pb))*f[i+j][j]
*/
#include<bits/stdc++.h>
#define ll long long
const int ha=1000000007;
const int maxn=1005;
int inv[2000005];
int n,pa,pb;
int f[2005][1005]; inline void init(){
inv[1]=1;
for(int i=2;i<=2000000;i++) inv[i]=-inv[ha%i]*(ll)(ha/i)%ha+ha;
} inline int add(int x,int y){
x+=y;
if(x>=ha) return x-ha;
else return x;
} inline void dp(){
int base=(pa*(ll)inv[pb]+(ll)n)%ha;
int PA=pa*(ll)inv[pa+pb]%ha,PB=pb*(ll)inv[pa+pb]%ha;
for(int i=n-1;i>=0;i--){
for(int j=n-i;j<=n;j++) f[i][j]=add(base,j-n+i);
for(int j=n-i-1;j;j--) f[i][j]=add(f[i][j+1]*(ll)PA%ha,f[i+j][j]*(ll)PB%ha);
f[i][0]=f[i][1];
}
} int main(){
init();
scanf("%d%d%d",&n,&pa,&pb);
dp();
printf("%d\n",f[0][0]);
return 0;
}
Codeforces 908 D New Year and Arbitrary Arrangement的更多相关文章
- Codeforces 908 D.New Year and Arbitrary Arrangement (概率&期望DP)
题目链接:New Year and Arbitrary Arrangement 题意: 有一个ab字符串,初始为空. 用Pa/(Pa+Pb)的概率在末尾添加字母a,有 Pb/(Pa+Pb)的概率在末尾 ...
- 【CodeForces】908 D. New Year and Arbitrary Arrangement
[题目]Good Bye 2017 D. New Year and Arbitrary Arrangement [题意]给定正整数k,pa,pb,初始有空字符串,每次有pa/(pa+pb)的可能在字符 ...
- CF 908 D New Year and Arbitrary Arrangement —— 期望DP
题目:http://codeforces.com/contest/908/problem/D 首先,设 f[i][j] 表示有 i 个 a,j 个 ab 组合的期望,A = pa / (pa + pb ...
- [CodeForces]908D New Year and Arbitrary Arrangement
设状态f[i][j]表示有i个a,j个ab的期望 发现如果i+j>=k的话就再来一个b就行了. #include <iostream> #include <cstdio> ...
- Codeforces New Year and Arbitrary Arrangement
New Year and Arbitrary Arrangement time limit per test2 seconds You are given three integers k, pa a ...
- Codeforces 908D New Year and Arbitrary Arrangement(概率DP,边界条件处理)
题目链接 Goodbye 2017 Problem D 题意 一个字符串开始,每次有$\frac{pa}{pa+pb}$的概率在后面加一个a,$\frac{pb}{pa+pb}$的概率在后面加一个 ...
- CF 908D New Year and Arbitrary Arrangement——期望dp
题目:http://codeforces.com/contest/908/problem/D 注意是子序列.加一个a对ab个数无影响:加一个b使ab个数多出它前面的a那么多个.所以状态里记录有多少个a ...
- Good Bye 2017 D. New Year and Arbitrary Arrangement
看了别人的题解 首先这题是一个dp dp[i][j] i是当前有多少个a j是当前有多少个ab子序列 dp[i][j] = dp[i+1][j]*Pa + dp[i][i+j]*Pb; i,j 时加一 ...
- CF908D Arbitrary Arrangement
题目大意: 给定三个数\(k\) , \(p_a\) , \(p_b\) 每次有\(\frac{p_a}{p_a+p_b}\)的概率往后面添加一个'a' 每次有\(\frac{p_b}{p_a+p_b ...
随机推荐
- 解决使用Oracle数据库,项目启动由于表原因无法成功启动问题
1.仔细看异常信息,如果出现一个 翻译过来是 不仅仅这一张表,那就说明,在连接数据库,定位到表的时候有多张表,不知道连哪一张. 原因: 有多个用户,这两个用户下有相同的表. 就算是在不同的表空间也不 ...
- java程序员笑不死的经历ส้้้้้้้้้
ส้้้้้้้้้้ส้้้้้้้้้้ส้้้้้้้้้ 1.程序猿最烦两件事,第一件事是别人要求他给自己的代码写文档,第二件呢?是别人的程序没有留下文档. 2.宪法顶个球!中国的法律都是.t ...
- 1020 Tree Traversals (25 分)(二叉树的遍历)
给出一个棵二叉树的后序遍历和中序遍历,求二叉树的层序遍历 #include<bits/stdc++.h> using namespace std; ; int in[N]; int pos ...
- 线段树(单点更新,区间查询) HDU 1754 I Hate It
题目链接 线段树的模板 #include<iostream> #include<cstdio> #include<cmath> #include<algori ...
- 一个画ROC曲线的封装包
Draw_ROC_Curves This is a python file which is used for drawing ROC curves -f : assign file name -t ...
- nyoj 题目44 子串和
子串和 时间限制:5000 ms | 内存限制:65535 KB 难度:3 描述 给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最 ...
- InputStream 、 InputStreamReader 、 BufferedReader
1.InputStream.OutputStream 处理字节流的抽象类 InputStream 是字节输入流的所有类的超类,一般我们使用它的子类,如FileInputStream等. OutputS ...
- GCC 中 -L、-rpath和-rpath-link的区别
GCC 中 -L.-rpath和-rpath-link的区别 来源 http://blog.csdn.net/q1302182594/article/details/42102961 关于这3个参数的 ...
- 刷题总结——子串(NOIP2015)
题目: 题目背景 NOIP2015 提高组 Day2 T2 题目描述 有两个仅包含小写英文字母的字符串 A 和 B .现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在 ...
- saltstack 实现redis主从
centos7.4 172.16.80.5 redis 主 172.16.80.6 redis 从 目录结构如下 file_roots: base: - /srv/salt/base dev: ...