Discription

You are given three integers kpa 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

Input
1 1 1
Output
2
Input
3 1 4
Output
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的更多相关文章

  1. Codeforces 908 D.New Year and Arbitrary Arrangement (概率&期望DP)

    题目链接:New Year and Arbitrary Arrangement 题意: 有一个ab字符串,初始为空. 用Pa/(Pa+Pb)的概率在末尾添加字母a,有 Pb/(Pa+Pb)的概率在末尾 ...

  2. 【CodeForces】908 D. New Year and Arbitrary Arrangement

    [题目]Good Bye 2017 D. New Year and Arbitrary Arrangement [题意]给定正整数k,pa,pb,初始有空字符串,每次有pa/(pa+pb)的可能在字符 ...

  3. 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 ...

  4. [CodeForces]908D New Year and Arbitrary Arrangement

    设状态f[i][j]表示有i个a,j个ab的期望 发现如果i+j>=k的话就再来一个b就行了. #include <iostream> #include <cstdio> ...

  5. Codeforces New Year and Arbitrary Arrangement

    New Year and Arbitrary Arrangement time limit per test2 seconds You are given three integers k, pa a ...

  6. Codeforces 908D New Year and Arbitrary Arrangement(概率DP,边界条件处理)

    题目链接  Goodbye 2017 Problem D 题意  一个字符串开始,每次有$\frac{pa}{pa+pb}$的概率在后面加一个a,$\frac{pb}{pa+pb}$的概率在后面加一个 ...

  7. CF 908D New Year and Arbitrary Arrangement——期望dp

    题目:http://codeforces.com/contest/908/problem/D 注意是子序列.加一个a对ab个数无影响:加一个b使ab个数多出它前面的a那么多个.所以状态里记录有多少个a ...

  8. 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 时加一 ...

  9. CF908D Arbitrary Arrangement

    题目大意: 给定三个数\(k\) , \(p_a\) , \(p_b\) 每次有\(\frac{p_a}{p_a+p_b}\)的概率往后面添加一个'a' 每次有\(\frac{p_b}{p_a+p_b ...

随机推荐

  1. [转]JS获取URL传参方法

    function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...

  2. 源码分析(一) HashMap 源码分析|JDK8

    HashMap是一个普遍应用于各大JAVA平台的最最最常用的数据结构.<K,V>的存储形式使HashMap备受广大java程序员的喜欢.JDK8中HashMap发生了很大的变化,例如:之前 ...

  3. Opencv3.0.0安装包

    这个资源是Opencv3.0.0安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载

  4. ERC720和erc721的区别

    有一阵子,Ethereum网络突然变的特别拥堵,原因是兴起了一款以太坊养猫的Dapp游戏,超级可爱的猫形象,再加上配种,繁殖和拍卖等丰富的玩法,风靡了币圈. 一时间币圈大大小小的人都在撸猫,以太坊网络 ...

  5. Small组件化重构安卓项目

    如果从一开始就没有设计好 后面项目业务比较大的时候很难掉头

  6. [blockchain-035]eos的部署安装智能合约

    0.参考资料 https://github.com/EOSIO/eos/wiki 1. eos的github地址 https://github.com/EOSIO/eos 2.下载eos源码 git ...

  7. Command Pattern的简单介绍

    Command pattern 的角色有:Command(抽象命令).ConcreteCommand(具体命令) .Invoker(传达命令者) .receiver(接收命令者)Client(客户类, ...

  8. urllib2.URLError: <ulropn error [Errno 10060] >

    在抓网页的时候,如果抓取频率很高,很容易出现这个错误: 意思是服务器拒绝响应.解决的方法为,隔段时间再试,不过这个方法不靠谱.靠谱的方法是增加一个延迟函数 import time time.sleep ...

  9. WKWebview 和 WebViewJavascriptBridge

    WKWebview 和 WebViewJavascriptBridge https://www.cnblogs.com/L-vincen/p/6681435.html 链接在这里,有很多不错的文章,大 ...

  10. 强制打开qq

    (function(){ var QQ='10001'; //换成你公司的企业QQ(客服QQ) var str='tencent://message/?Menu=yes&uin='+QQ+'& ...