codeforces 838D D.Airplane Arrangements 思维构造+排列组合

来源:互联网 发布:怎么找淘宝刷手的工作 编辑:程序博客网 时间:2024/06/04 00:29

参考网上唯一一发题解  感谢!


题目链接


题意:


航空公司卖机票。飞机座位是1~n的,卖m张票,m小于等于n,每张票上有三个信息,票号 i,座位号 j,登机入口

k,登机入口指的是从机头进入或者是从机尾进入。

乘客登飞机规则:

1. 乘客按照机票的编号从小到大依次登机。

2. 乘客登飞机时,从票上指定的入口进入,径直走到自己的位置处,如果有人,就看下一个位置有没有人,直到找

到第一个空座位,便入座,如果一直走到头都没有位置,该乘客就会暴走。

航空公司想知道它有多少种印票方式,使得乘客不暴走。其中,票上的座位号可以重复。两种印票方式不同当且仅

当两套票中存在票号为 i 的票,票上的信息不完全一样。



思路:

这个题自己想了好久,还和别人讨论过,但是吧还是不太好想,最后还算是说服了自己吧.大牛们千篇一律得出同样的

式.

这个题目的一堆条件确实让我感到了蒙蔽, 首先还要考虑进入的方向,编号,还有重叠的,感觉无法下手.

我们可以知道从前门进入一直走到后门没找到位置,和从后门进入一直走到前门没找到位置是等价的.我们可以设置

一个虚拟的位置,这样就构成一个有n+1个位置的环,那么前门后门进入就可以想象成顺时针和逆时针,起点都是那个没

座的位置。那么我们知道所有可能的印票数位2^m * (n+1)^m. 2 ^ m 是由于左右方向.这其中还包含非法的,那么我们

要把非法的减掉,非法的就是1个人没座 2个人没座 3个人没座....m个没座(当然m个实际不存在).那么环上要使某一个

特定位置为空的情况占总情况数的: (n-m+1)/(n+1) 约分得到最后结果为: 2^m *(n+1)^(m-1)*(n+1-m)

其实把公式展开 (2(n+1))^m-2^m*(n+1)^(m-1)*C(m,1).

因为非法的其实就是保证至少有一个人坐在虚拟位置,那么就是C(m,1) 保证至少一人坐在虚拟位置,其余的人随

便坐,那么就有2^m*(n+1)^(m-1)*C(m,1).


#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll mod = 1e9 + 7;ll qmod(ll a,ll b){    ll res = 1;    while(b)    {        if(b&1)            res = res * a % mod;        a = a * a % mod;        b >>= 1;    }    return res;}int main(){    ll n,m;    scanf("%lld %lld",&n,&m);    ll ans = qmod(2 ,m) * qmod(n + 1,m - 1) % mod * (n- m + 1) % mod;    printf("%lld\n",ans % mod);    return 0;}




原创粉丝点击