Description
电影院有 n 位置,每个位置两边都有一个放水杯的槽,相邻两个位置分享同一个槽,看电影的人按顺序进场,先进场的人会把其座位两边没人用的槽都占了,如果一个人进场后发现其座位两边槽都被占了就会不满意,现在给出一部分位置的人进场的顺序,要求给没确定进场顺序的位置安排进场顺序使得所有看电影的人都很满意,问方案数
Input
第一行一整数
Output
输出方案数,结构模 109+7
Sample Input
11
0 0 0 0 0 0 0 0 0 0 0
Sample Output
1024
Solution
第一个进场的人会占两个槽,后面的人要想每人至少一个槽就只能一人一个,也就是说后面进场的人必须坐在一个之前进场的人的旁边,把所有进场顺序确定的位置按(位置 pos ,进场顺序 val )存下来,按进场顺序排序升序排
分两种情况考虑,第一个进场的人位置没有确定,第一个进场的人位置已经确定。如果第一个进场的人位置没有确定,就枚举其位置,故只要求出第一个进场的人位置确定时的方案数即可
按进场顺序一个个将已经确定顺序的人放进去,假设当前已经坐满的位置区间为
[l,r]
,初始时
l,r
均为第一个进场的人的位置,然后按已经排好序的(位置,进场顺序)把这些进场顺序确定的人放好,假设当前人第
val
个进场,要坐在第
pos
个位置,上一个(确定顺序的)进场的人是第
pre
个进场的,那么这两个人之间有
val−pre−1
个人,如果
pos
在
[l,r]
之间显然不行,一个位置只能坐一个人,只考虑
pos<l
的情况,
pos>r
的情况类似,这
val−pre−1
个人进场时只有两个选择,从
l
开始往左扩展,从
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100005;
#define mod 1000000007
int fact[maxn],inv[maxn];
void init(int n=1e5)
{
fact[0]=1;
for(int i=1;i<=n;i++)fact[i]=(ll)i*fact[i-1]%mod;
inv[1]=1;
for(int i=2;i<=n;i++)inv[i]=mod-(ll)(mod/i)*inv[mod%i]%mod;
inv[0]=1;
for(int i=1;i<=n;i++)inv[i]=(ll)inv[i-1]*inv[i]%mod;
}
int C(int n,int m)
{
return (ll)fact[n]*inv[m]%mod*inv[n-m]%mod;
}
struct node
{
int pos,val;
bool operator<(const node&b)const
{
return val<b.val;
}
}a[maxn];
void add(int &x,int y)
{
x=x+y>=mod?x+y-mod:x+y;
}
int n,m;
int Solve(int pos,int i)
{
int l=pos,r=pos,ans=1,pre=1;
for(;i<m;i++)
{
if(a[i].pos<l)
{
int dval=a[i].val-pre-1,dpos=l-a[i].pos-1;
if(dpos>dval)return 0;
ans=(ll)ans*C(dval,dpos)%mod;
l=a[i].pos,r+=dval-dpos,pre=a[i].val;
}
else if(a[i].pos>r)
{
int dval=a[i].val-pre-1,dpos=a[i].pos-r-1;
if(dpos>dval)return 0;
ans=(ll)ans*C(dval,dpos)%mod;
r=a[i].pos,l-=dval-dpos,pre=a[i].val;
}
else return 0;
}
return ans;
}
int main()
{
init();
while(~scanf("%d",&n))
{
m=0;
for(int i=1;i<=n;i++)
{
int temp;
scanf("%d",&temp);
if(temp)a[m++]=(node){i,temp};
}
a[m++]=(node){n+1,n+1};
sort(a,a+m);
int ans=0;
if(a[0].val==1)add(ans,Solve(a[0].pos,1));
else
for(int i=1;i<=n;i++)add(ans,Solve(i,0));
printf("%d\n",ans);
}
return 0;
}