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

题目:http://codeforces.com/contest/908/problem/D

注意是子序列。加一个a对ab个数无影响;加一个b使ab个数多出它前面的a那么多个。所以状态里记录有多少个a和ab。

当 i+j>=k 的时候,再加一个b就结束了。用式子算一下期望,发现一个等比数列;用等比数列的公式算一下,变成一个值减去一个无限小的值,所以就是那个值了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1005,mod=1e9+7;
int n,A,B,tmp,C,dp[N][N];
bool vis[N][N];
int pw(int x,int k)
{
    int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;
}
int dfs(int i,int j)
{
    if(vis[i][j])return dp[i][j];
    vis[i][j]=1;
    if(i+j>=n) return dp[i][j]=(i+j+C)%mod;
    dp[i][j]=((ll)A*dfs(i+1,j)+(ll)B*dfs(i,i+j))%mod;
    return dp[i][j];
}
int main()
{
    scanf("%d%d%d",&n,&A,&B);
    tmp=pw(A+B,mod-2); C=(ll)A*pw(B,mod-2)%mod;
    A=(ll)A*tmp%mod; B=(ll)B*tmp%mod;
    printf("%d
",dfs(1,0));
    return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9675488.html