• 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;
    }
    



  • 相关阅读:
    字符串拆分成泛型列表
    第一次写博客
    获取最长的增长列表
    oracle 一些小资料
    XML 序列化出错
    Redis学习(一)
    SQL和NoSQL的区别
    SpringBoot中文乱码解决方法
    从visual studio 2012生成预处理代码&汇编码
    近期流水账
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672498.html
Copyright © 2020-2023  润新知