题目链接

总结:组合数

这$F$题好难啊...只会部分分做法,下面两个方法都是部分分做法。满分做法我去看看...会的话就补一下

部分分做法

方法1:

首先$A$能赢的条件很明显,假设在所有的牌里面取出$A$张$A$牌,$B$张$B$牌,$C$张$C$牌,那么$A$能赢当且仅当$A=n,B<m,C<k$

所以假设我们在拿出了$n$张$A$牌的情况下,中间穿插着拿了$B$张$B$牌,$C$张$C$牌,则有

$$\sum_{i=0}^{i<=m+k}C(n-1,i+n-1)*3^{m+k-i}*\sum_{j=0}^{j<=m,j<=k}C(i,j)$$

首先在$i+n-1$张牌中取$n-1$张$A$牌的方案为$C(n-1,n+i-1)$

注意:最后一张牌一定需要是$A$,所以就只能有$n-1$

而且剩下的牌数的排列为$3^{m+k-i}$,要乘上去

以及在$i+n-1$中$B$和$C$的排列为$C(i,j)$,也要乘起来

所以就得到了上面的公式

但是,上面的做法我打挂了...这个式子是对的,我算后面那个$\sum_{j=0}^{j<=m,j<=k}C(i,j)$那里我没有枚举好...查不出来啊...

 

我在理解了满分做法之后终于发现我挂在哪里了...

在枚举后面的东西的时候我没有分类讨论。但是改完后貌似还分少了一类...

$subtask_1$10个点我错了$2$个...然后$subtask_2$被我强行水过去$2$个点..

用$C$牌数量来分类:分为$j<k$,$j<m$,$j<i$(第三类我没分...不想去改了...)

对于第一种情况:$x=\sum_{j=0}^{j<k}C(i,j)$

对于第二种情况:$x=\sum_{j=0}^{j<m}C(i,k)$

对于第三种情况:请读者独立思考(知道有第三种情况是因为我去看了一下满分的做法...)

 

#include <bits/stdc++.h>

using namespace std ;

#define N 5010
#define ll long long
const int mod = 1e9 + 7 ;

int n , m , k ;
ll fac[ N ] , ifac[ N ] ;

ll power( ll a ,ll b ) {
    ll base = a , ans = 1 ;
    while( b ) {
        if( b&1 )  ans = ( ans * base ) % mod ;
        base = ( base * base ) % mod ;
        b >>= 1 ;
    }
    return ans ;
}
ll mul( ll x ,ll y ) {
    return ( 1ll * x * y ) % mod ;
}

ll inv( ll x ) {
    return power( x , mod - 2 ) % mod ;
}

int main() {
    scanf( "%d%d%d" , &n , &m , &k ) ;
    
    fac[ 0 ] = 1 ;
    for( int i = 1 ; i < N ; i ++ ) fac[ i ] = mul( fac[ i - 1 ] , i ) ;
    for( int i = 0 ; i < N ; i ++ ) ifac[ i ] = inv( fac[ i ] ) ;
    
    ll ans = 0 , sum = n + k + m ;
    
    for( int i = n ; i <= sum; i ++ ) {// 取出n张A牌 
        for( int j = 0 ; j <= m ;j ++ ) {//B牌数量 
            int C = i - n - j ;//C牌数量 
            if( C < 0 || C > k ) continue ;
            ll tmp = mul( fac[ i - 1 ] , mul( ifac[ n - 1 ] , mul( ifac[ j ] ,ifac[ C ] ) ) ) ;
            tmp = mul( tmp , power( 3 , sum - i ) ) ;
            ans = ( ans + tmp ) % mod ;
        }
    }
    
    printf( "%lld\n" , ans ) ;
    
}
部分分做法1(有一定错误...)

相关文章: