NC50777. 毕业生的序列游戏
描述
现在,你需要求出该算法所构造出来的序列中'ab'子序列的期望个数为多少。显然,该结果可以用P/Q来表示,其中P和Q互质,并且Q≠0,P和Q模数为1e9+7。你需要打印出(P/Q)mod(1e9+7)。
注意,子序列是可以不连续的。
输入描述
第一行包含三个整数k,PA,PB(1≤k≤1000,1≤PA,PB≤1000000)。
输出描述
输出一个整数
示例1
输入:
1 1 1
输出:
2
C++11(clang++ 3.9) 解法, 执行用时: 32ms, 内存消耗: 11740K, 提交时间: 2019-07-06 16:56:11
#include<bits/stdc++.h> #define ll long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const ll mod=1e9+7; ll k,a,b,fm,f[1005][2005]; ll qpow(ll x,ll k) { ll ret=1; while(k){ if(k&1) ret*=x,ret%=mod; x*=x; x%=mod; k>>=1; } return ret; } int main() { cin>>k>>a>>b; fm=qpow(a+b,mod-2)%mod; ll ans=0,t=a*qpow(b,mod-2)%mod; f[1][0]=1; for(int i=1;i<=k;i++){ for(int j=0;j<=k;j++){ if(i+j>=k){ ans=(ans+f[i][j]*((i+j+t)%mod)%mod)%mod; } else{ f[i][i+j]+=(f[i][j]*b%mod*fm%mod); f[i][i+j]%=mod; f[i+1][j]+=(f[i][j]*a%mod*fm%mod); f[i+1][j]%=mod; } } } cout<<ans<<endl; return 0; }
C++14(g++5.4) 解法, 执行用时: 23ms, 内存消耗: 7912K, 提交时间: 2020-03-02 12:19:35
#include<bits/stdc++.h> using namespace std; const int mod=1e9+7; long long k,pa,pb,invb,invab; long long dp[1010][1010]; long long quick_pow(long long a,long long b) { long long ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } long long dfs(long long x,long long y) { if(dp[x][y]!=0) return dp[x][y]; if(x+y>=k) return dp[x][y]=(x+y+pa*invb%mod)%mod; return dp[x][y]=(pa*invab%mod*dfs(x+1,y)%mod+pb*invab%mod*dfs(x,x+y)%mod)%mod; } int main() { cin>>k>>pa>>pb; invb=quick_pow(pb,mod-2); invab=quick_pow(pa+pb,mod-2); cout<<dfs(1,0)<<endl; return 0; }