[Codeforces37D]Lesson Timetable
阿新 • • 發佈:2018-12-24
題目大意
有m個教室,第i個教室最多能容納Yi組人,初始時第i個教室有Xi組人。
現在每組人要從當前所在的教室a移動到教室b(a≤b)。我們不知道第i組人初始在哪間教室,以及它要去哪間教室,求可能的方案數。答案對
資料範圍
1≤m≤100 0<
思路
設s[i]=
先無視每個組的編號,然後設f[i][j]為初始前i個教室,已經分配了j組人的新教室,方案數為多少。轉移顯然:
其中k列舉的是放在教室i的組數,注意0≤k≤Y[i]。
那麼f[m][s[m]]就是要求的答案了。加上每組人編號的影響:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int mo=1e9+7;
int n,m,s[105],f[105][1005],Fact[1005],Ie[1005],X[105],Y[105];
int quick(int x,int y)
{
if (!y) return 1;
int tmp=quick(x,y/2 );
tmp=(LL)tmp * tmp % mo;
if (y % 2==1) tmp=(LL)tmp*x % mo;
return tmp;
}
int C(int n,int m)
{
return (LL)Fact[n] * Ie[m] % mo * Ie[n-m] % mo;
}
int main()
{
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&X[i]);
s[i]=s[i-1]+X[i];
}
n=s[m];
for (int i=1;i<=m;i++) scanf("%d",&Y[i]);
Fact[0]=Ie[0]=1;
for (int i=1;i<=n;i++)
{
Fact[i]=(LL)Fact[i-1]*i % mo;
Ie[i]=quick(Fact[i],mo-2);
}
f[0][0]=1;
for (int i=1;i<=m;i++)
{
for (int j=0;j<=s[i];j++)
{
for (int k=0;k<=min(j,Y[i]);k++)
{
f[i][j]=(f[i][j]+(LL)f[i-1][j-k] * C(s[i]-j+k,k) % mo) % mo;
}
}
}
int ans=f[m][n];
for (int i=1;i<=m;i++) ans=(LL)ans * C(n-s[i-1],X[i]) % mo;
printf("%d\n",ans);
return 0;
}