hdu5651xiaoxin juju needs help(大组合数模板)

来源:互联网 发布:英国哪个城市最美 知乎 编辑:程序博客网 时间:2024/06/08 00:33

题意:问一个字符串任意排列,能组成多少个回文串。
思路:统计每个字母出现次数,如果超过两个次数是奇数就不满足回文串。满足回文串的话,统计数量就是统计半边字母的排列组合的情形。
很容易想到组合的公式。但由于数据是500很大,只能求救模板…

const int maxn=500+10;const long long mod=1000000007;long long c[maxn][maxn],a[30];void init(int n,int m){    memset(c,0,sizeof(c));    for(int i=0;i<=m;i++) c[0][i]=c[1][i]=c[i][i]=1;    for(int i=0;i<n;i++) c[i][0]=1;    for(int i=1;i<=n;i++){        for(int j=1;j<i;j++){            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;        }    }}
#include<bits/stdc++.h>using namespace std;const int maxn=500+10;const long long mod=1000000007;long long c[maxn][maxn],a[30];void init(int n,int m){    memset(c,0,sizeof(c));    for(int i=0;i<=m;i++) c[0][i]=c[1][i]=c[i][i]=1;    for(int i=0;i<n;i++) c[i][0]=1;    for(int i=1;i<=n;i++){        for(int j=1;j<i;j++){            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;        }    }}int main(){    init(500,500);    int T;scanf("%d",&T);    while(T--){        string s;cin>>s;        memset(a,0,sizeof(a));        for(int i=0;i<s.size();i++){            a[s[i]-'a']++;        }        int cnt=0,sum=0;        for(int i=0;i<26;i++){            sum+=a[i];            if(a[i]%2){            cnt++,a[i]--;            }        }        if(cnt>1) {            printf("0\n");            continue;        }        long long ans=1;sum/=2;        for(int i=0;i<26;i++){            if(a[i]){                ans=(ans*c[sum][a[i]/2])%mod;                sum-=a[i]/2;            }        }        printf("%lld\n",ans);    }}
0 0
原创粉丝点击