码迷,mamicode.com
首页 > 其他好文 > 详细

第八场 hdu 6143 Killer Names(思维题)

时间:2017-08-18 22:26:00      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:条件   mem   stream   解题思路   problem   name   eof   get   memset   

http://acm.hdu.edu.cn/showproblem.php?pid=6143

题目大意:有名和姓两种字符串,每种字符串长度都是n个字符,名和姓加起来的字符种类数最多是m个,问满足条件的字符串有多少种?

解题思路:我们能够枚举左边的字符种数是x,那么右边就有(m-x)n种排列方式。我们知道左边的排列方式数量是C(m,x)*f(x)。其中f(x)=(xn-C(x,x-1)*f(x-1)-C(x,x-2)*f(x-2)……C(x,1)*f(1))。最后结果就是枚举每一个x,对C(m,x)*f(x)*(m-x)n求和就可以了。

AC代码:

 

 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const long long mod=1e9+7;
 5 long long a[2005][2005],num[2005];
 6 long long  pow_(int n,int m)
 7 {
 8     long long tmp=m,ans=1;
 9     while(n)
10     {
11         if(n&1)
12         {
13             ans=(ans*tmp)%mod;
14         }
15         tmp=(tmp*tmp)%mod;
16         n=n/2;
17     }
18     return ans%mod;
19 }
20 int main()
21 {
22     int t,n,m;
23     for(int i=1;i<=2002;i++)
24     {
25         a[i][0]=1,a[i][i]=1;
26         for(int j=1;j<i;j++)
27         {
28             a[i][j]=(a[i-1][j-1]+a[i-1][j]+mod)%mod;
29         }
30     }
31     while(~scanf("%d",&t))
32     {
33         while(t--)
34         {
35             memset(num,0,sizeof(num));
36             scanf("%d%d",&n,&m);
37             long long ans,tmp=1;
38             if(m>n)
39             {
40                 ans=0,tmp=0;
41                 for(int i=1;i<=n;i++)
42                 {
43                     tmp=0;
44                     for(int j=1;j<i;j++)
45                     tmp=(tmp+a[i][j]*num[j])%mod;
46                     num[i]=(pow_(n,i)-tmp+mod)%mod;
47                     ans=(ans+(((a[m][i]*num[i])%mod)*pow_(n,m-i))%mod+mod)%mod;
48                 }
49             }
50             else
51             {
52                 ans=0,tmp=0;
53                 for(int i=1;i<=m-1;i++)
54                 {
55                     tmp=0;
56                     for(int j=1;j<i;j++)
57                     tmp=(tmp+a[i][j]*num[j])%mod;
58                     num[i]=(pow_(n,i)-tmp+mod)%mod;
59                     ans=(ans+(((a[m][i]*num[i])%mod)*pow_(n,m-i))%mod+mod)%mod;
60                 }
61             }
62             printf("%lld\n",ans%mod);
63         }
64     }
65     return 0;
66 }

 

第八场 hdu 6143 Killer Names(思维题)

标签:条件   mem   stream   解题思路   problem   name   eof   get   memset   

原文地址:http://www.cnblogs.com/wang-ya-wei/p/7392187.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!