counting the buildings

2017-08-10 21:10:08

writer:pprp

//TLE
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 2020;

ll dp[maxn][maxn];

const int mod = 1e9 + 7;

void S1()
{
    for(int i = 1 ; i <= 20 ; i++)
    {
        dp[i][0] = 0;
        dp[i][i] = 1;
        for(int j = 1; j < i ; j++)
            dp[i][j] = (i - 1) * dp[i-1][j] + dp[i-1][j-1];
    }
}

//a^b%m 快速幂
int quick_power_mod(int a, int b, int m)
{
    int result = 1;
    int base = a;
    while(b > 0)
    {
        if(b&1 == 1)//如果b是奇数
        {
            result = (result * base) % m;
        }
        base = (base * base)%m;
        b>>=1;
    }
    return result;
}

//组合数取模 C(a,b)%p
ll composition(ll a, ll b, int p)
{
    if(a < b)
        return 0;
    if(a == b)
        return 1;
    if(b > a - b) b = a - b;

    int ans = 1, ca  = 1, cb = 1;
    for(ll i = 0 ; i < b; i++)
    {
        ca = (ca * (a - i))%p;
        cb = (cb * (b - i))%p;
    }

    ans = (ca * quick_power_mod(cb,p - 2, p)) % p;
    return ans;
}

ll lucas(ll n, ll m, ll p)
{
    ll ans = 1;
    while(n && m && ans)
    {
        ans = (ans * composition(n%p, m%p, p))%p;
        n /= p;
        m /= p;
    }
    return ans;
}


int main()
{
    S1();
    int T;
    cin >> T;
    int N, F, B;

    while(T--)
    {
        cin >> N >> F >> B;
        cout << dp[N-1][F+B-2]*composition(F+B-2,F-1,mod) <<endl;
    }
    return 0;
}

标解:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 2020;

ll dps[maxn][maxn];
ll dpc[maxn][maxn];

const ll mod = 1e9 + 7;

 void init()
 {
       for(int i = 0; i < maxn ; i++)
       {
             dpc[i][0] = dpc[i][i] = dps[i][i] = 1;
             for(int j = 1; j < i ; j++)
             {
                   dpc[i][j] = (dpc[i-1][j-1]+dpc[i-1][j])%mod;
                   dps[i][j] = ((i-1)*dps[i-1][j])%mod + dps[i-1][j-1]%mod;
             }
       }
 }

int main()
{ 
    int T;
    cin >> T;
    long long N, F, B;
    init();

    while(T--)
    {
        cin >> N >> F >> B;
        cout << dps[N-1][F+B-2]*dpc[F+B-2][F-1]%mod <<endl;
    }
    return 0;
}

标解中组合数是用杨辉三角求解的

杨辉三角dp法

dp[i][j]=dp[i-1][j-1]+dp[i-1][j]

O(n^2)~O(1)

原文地址:https://www.cnblogs.com/pprp/p/7341508.html