2017 Multi-University Training Contest - Team 8

HDU6140 Hybrid Crystals

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6140

题目意思:这场多校是真的坑,题目爆长,心态爆炸,题目意思就是给定一个序列。序列的每个值都有属性,N代表可加可减,L代表只能加,D代表只能减,当然这些都可以用或者不用。给定一个k,问k是否可能用这个序列构成。

思路: 源头都来自这个奇怪的式子

解释一下这个式子什么意思:

如果b[i]是N那么所有b[j](j<i)属性是N的和大于b[i]。

如果b[i]是L那么所有b[j](j<i)属性是N和L的和小于b[i]。

如果b[i]是L那么所有b[j](j<i)属性是N和R的和小于b[i]。

偷个懒直接把题解截图过来。因为题目保证一开始a[1]=1,且type=N,那么一开始我们可以表示[-1,1]范围内的整数,现在a[2]<=a[1],假设a[2]=1,那么如果type为L那么我们现在就可以表示[-2,1]范围内的所有整数了,如果type为R就可以表示[-1,2]范围内的整数了。所以以此类推,再结合上述题解中的解释,我们只需要从头到尾扫一遍就知道,是否可以构成指定整数了,思维题啊!!!

代码:

 1 //Author: xiaowuga
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <set>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <cstring>
 9 #include <cstdio>
10 #include <ctime>
11 #include <map>
12 #include <bitset>
13 #include <cctype>
14 #define maxx INT_MAX
15 #define minn INT_MIN
16 #define inf 0x3f3f3f3f
17 #define mem(s,ch) memset(s,ch,sizeof(s))
18 #define nc cout<<"nc"<<endl
19 #define sp " "
20 const long long N=100000; 
21 using namespace std;
22 typedef long long LL;
23 typedef int II;
24 II n,k;
25 II a[1000+10];
26 char  b[1000+10];
27 int main() {
28     ios::sync_with_stdio(false);cin.tie(0);
29     II T;
30     cin>>T;
31     while(T--){
32         cin>>n>>k;            
33         for(II i=0;i<n;i++) cin>>a[i];
34         for(II i=0;i<n;i++){
35             cin>>b[i]; 
36         }
37         II l=0,r=0;
38         for(II i=0;i<n;i++){
39             if(b[i]=='N'){l-=a[i]; r+=a[i];}
40             else if(b[i]=='L') r+=a[i];
41             else l-=a[i];
42         }
43         if(k>=l&&k<=r) cout<<"yes"<<endl;
44         else cout<<"no"<<endl;
45     }
46     return 0;
47 }
View Code

HDU6143  Killer Names

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6143

题目意思:要求构造若干名字,名字包括 first name last name 两部分,均需包含 n 个字符,已知有 m 种字符供选择,求最多有多少种不同的构造方法,使得 first name 和 last name 不含相同字符。

题目思路:不想说什么……组合数学,自己百度第二类斯特林数,公式就是∑C(m,i)*S(n,i)*A[i]*(m-i)^n,好好理解一下这个公式,第二类斯特林数就是n个无差别的坑和i个东西,要把东西放进去有多少种放法,现在注意我们这里是有差别的,所以再乘一个阶乘数就可以了。

代码:

 1 //Author: xiaowuga
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <set>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <cstring>
 9 #include <cstdio>
10 #include <ctime>
11 #include <map>
12 #include <bitset>
13 #include <cctype>
14 #define maxx INT_MAX
15 #define minn INT_MIN
16 #define inf 0x3f3f3f3f
17 #define mem(s,ch) memset(s,ch,sizeof(s))
18 #define nc cout<<"nc"<<endl
19 #define sp " "
20 const long long N=2000+5; 
21 const long long mod=1e9+7;
22 using namespace std;
23 typedef long long LL;
24 typedef int II;
25 LL C[N][N]={0},S[N][N]={0},A[N]={0};
26 void init(){
27     for(II i=0;i<N;i++) C[i][0]=1;
28     for(II i=1;i<N;i++)
29         for(II j=1;j<=i;j++){
30             C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
31         } 
32     A[1]=1;
33     for(II i=2;i<N;i++){
34         A[i]=A[i-1]*i%mod;
35     }
36     for(II i=0;i<N;i++){
37         S[i][i]=1;
38         if(i>=1) S[i][0]=0;
39         for(II j=1;j<i;j++) 
40             S[i][j]=(j*S[i-1][j]+S[i-1][j-1]+mod)%mod;
41     }
42 }
43 LL q_power(LL a,LL k){
44     LL ans=1;
45     while(k){
46         if(k%2) ans=(ans*a%mod+mod)%mod;
47         k/=2;
48         a=(a*a%mod+mod)%mod;
49     }
50     return ans;
51 }
52 int main() {
53     ios::sync_with_stdio(false);cin.tie(0);
54     II T;
55     init();
56     cin>>T;
57     II n,m;
58     LL ans=0;
59     while(T--){
60         cin>>n>>m; 
61         ans=0;
62         for(II i=1;i<=m-1;i++){
63             LL t1=C[m][i]*S[n][i]%mod;
64             t1=t1*A[i]%mod;
65             LL t2=q_power((m-i),n)%mod;
66             LL tmp=t1*t2%mod;
67             ans=(ans+tmp)%mod;
68         }
69         cout<<ans<<endl;
70     }
71     return 0;
72 }
View Code

 

posted on 2017-09-15 21:50  xiaowuga  阅读(162)  评论(0编辑  收藏  举报

导航