xiaoxin juju needs help hdu(5651)杨辉三角与二项式

xiaoxin juju needs help

 
 Accepts: 150
 
 Submissions: 966
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
xiaoxin巨从小就喜欢字符串,六年级的时候他就知道了什么是回文串。这时,xiaoxin巨说到:如果一个字符串 SS 是回文串,那么该字符串从前往后看和从后往前看是一样一样的。

六年级的暑假,xiaoxin很快就做完了暑假作业,然后到腾讯做起了实习生。这日,leader给了xiaoxin一个字符串,请xiaoxin帮忙写一个函数来生成所有可能的回文串,可以任意改变字符串的顺序但是不可以扔掉某个字符。并且leader告诉xiaoxin,每生成一个不一样的回文串就可以得到一颗西瓜糖。

请你帮忙计算xiaoxin的leader最多需要买多少颗西瓜糖呢?
输入描述
多组测试数据。第一行包含一个整数 T(T\leq 20)T(T20) 表示组数。每组测试数据给出一个只包含小写字母的字符串 S(1\leq length(S)\leq 1,000)S(1length(S)1,000)
输出描述
对于每组测试数据,输出一个数, 表示leader需要买的西瓜糖的个数,结果对 1,000,000,0071,000,000,007 取模。
输入样例
3
aa
aabb
a
输出样例
1
2

1

解法:对于给定的一个字符串统计它字符出现的个数,由于回文串是相互对称的,所以如果存在两个字符出现为奇数的情况则不能构成回文串,ans=0。然后由于称的,就成了一个排列组合问题ans=C(n)s[0]*C(n-s[0])s[1].......C(n-s[0]-s[1]...s[i])s[i];但由于所给数据很大,要进行取摸运算。我们可以用杨辉三角的规律处理出所有的Cn(i),(这个也要取mod,否则会超ll).

AC:

#include #include #include #include #include using namespace std; #define maxn 1100 #define ll __int64 #define mod 1000000007 ll s[365]; ll cn[maxn][maxn]; void cni() {     memset(cn,0,sizeof(cn));     for(int i=0;i<=1000;i++)     {     cn[i][0]=1;     for(int j=1;j<=i;j++)     {         cn[i][j]=(cn[i-1][j-1]+cn[i-1][j])%mod;     }     } } int main() {   char ss[maxn];   ll t,pos,cnt,ans,tp;   cni();   scanf("%I64d",&t);   while(t--)   {       cnt=0;ans=1;       memset(s,0,sizeof(s));       scanf("%s",ss);       for(ll i=0;i=2) ans=0;       else       {          ll n; if(cnt==0) n=(strlen(ss))/2; else n=(strlen(ss)-1)/2; tp=n; if(n!=0)          for(int i=0;i<=365;i++)           {                 ans*=(cn[tp][s[i]])%mod;                 ans=ans%mod;                 tp-=s[i];           }       }       printf("%I64d\n",ans%mod);   }   return 0; }

你可能感兴趣的:(xiaoxin juju needs help hdu(5651)杨辉三角与二项式)