zoukankan      html  css  js  c++  java
  • hdu 6143 组合数学+dp

    题意: m个字母,组成两个长度为n的字符,其中一个字母不能同时出现在两个串中。问总方案?

    思路:枚举m个中恰好有i个在第一个串,有j个在第二个串。。然后求个和。。具体其中n个空恰好k种颜色,可以用dp预处理。

    dp[j][i]=((dp[j-1][i]*i)%mod+(dp[j-1][i-1]*i)%mod)%mod;

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define MEM(a,b) memset(a,b,sizeof(a))
    #define bug puts("bug");
    #define PB push_back
    #define MP make_pair
    #define X first
    #define Y second
    typedef unsigned long long ll;
    typedef pair<int,int> pii;
    const int maxn=4e5+10;
    const int mod=1e9+7;
    using namespace std;
    int t,m,n,k;
    ll C[2005][2005];
    ll dp[2005][2005];
    ll A(ll x){
        ll ret=1;
        for(int i=1;i<=x;i++)
            ret=(ret*i)%mod;
        return ret;
    }
    int main(){
        C[1][0] = C[1][1] = 1;
        for (int i = 2; i < 2005; i++){
            C[i][0] = 1;
            for (int j = 1; j < 2005; j++)
                C[i][j] = (C[i - 1][j] + C[i - 1][j - 1])%mod;
        }
        for (ll i = 1; i < 2005; i++){
            dp[i][i]=A(i);
            for (ll j = i+1; j < 2005; j++)
                dp[j][i]=((dp[j-1][i]*i)%mod+(dp[j-1][i-1]*i)%mod)%mod;
        }
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            ll ans=0;
            for(int i=1;i<m;i++)
                for(int j=m-i;j>0;j--){
                    ans=(ans+((C[m][i]*dp[n][i])%mod)*((C[m-i][j]*dp[n][j])%mod))%mod;
                }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    



  • 相关阅读:
    python_基础2
    springboot自定义配置文件类
    自定义实现spring-boot-starter-data-redis
    @ConditionalOnBean详解
    @Conditional详解
    并发包大神Doug Lea
    idea新建springboot项目
    springboot实现自定义start
    世界上唯一公平的事情就是每个人都会死。
    hashtable存null会发生什么?
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672498.html
Copyright © 2011-2022 走看看