row of seats

Topic link: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3370&konwledgeId=40

Problem-solving ideas: We can first arrange m people, the number of solutions is m!, and then consider inserting a space between two people, assuming that x0 spaces are inserted in front of the first person, between the first person and the second person Insert x1 spaces. . .

Then we have: x0+x1+x2+....+xm=nm (after removing m people, only nm positions are left). To meet the requirements of the title, no two people are adjacent, then, xi>=1 i=1,2,3,...,m-1.

Since the first person and the last person can be adjacent to each other, they need to be considered separately:

  1.  x0==0, then you need xm>=1
  2. xm==0, then you need x0>=1
  3.  x0>=1 && xm>=1

Consider the third case first, that is, x0+x1+x2+...+xm=nm, which can be calculated by the partition method. For example, x1+x2+x3=5, you can write 5 as 5=1+1+1+1+1, now you need to choose two of the four "+" signs, so that the last three numbers are added, so it is C(4-1, 3-1). For our problem we have ans=C(nm-1, m) (because there are m+1 numbers)

For the first and second cases, it is equivalent to x1+x2+...+m=nm, the solution is the same as above, ans=C(nm-1, m-1)

Finally add all the results together. The final result is: m!(C(nm-1,m) + 2*C(nm-1, m-1))

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int MAXN = 100005;
 6 const LL MOD7 = 1e9+7;
 7 
 8 LL n,m;
 9 LL pow(LL a, LL b, LL MOD)
10 {
11     LL ans = a%MOD;
12     LL res=1LL;
13     while (b)
14     {
15         if (b&1) res=res*ans%MOD;
16         ans=ans*ans%MOD;
17         b>>=1;
18     }
19     return res;
20 }
21 
22 LL inverse(LL a, LL p)
23 {
24     return pow(a,p,p-2);
25 }
26 
27 void solve(LL n, LL m)
28 {
29     LL ans=1LL;
30     for (int i=1;i<=m-1;++i) ans=ans*(n-m-1-i+1)%MOD7;
31     LL res=0LL;
32     res=(ans*m*2%MOD7+ans*(n-m*2)%MOD7)%MOD7;
33     printf("%lld\n",res);
34 }
35 
36 int main()
37 {
38 #ifndef ONLINE_JUDGE
39     freopen("test.txt","r",stdin);
40 #endif // ONLINE_JUDGE
41     int Case;
42     scanf("%d",&Case);
43     while (Case--)
44     {
45         scanf("%lld%lld",&n,&m);
46         if (n<2*m) printf("0\n");
47         else if (m==1LL) printf("%lld\n",n);
48         else solve(n,m);
49     }
50     return 0;
51 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324689972&siteId=291194637
Row