传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4559
思路:
真·乱证明↓
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
const ll mod = 1e9 + 7;
const ll maxv = 102;
ll quick_pow(ll a, ll b, ll m)
{
ll ans = 1;
while (b > 0)
{
if (b & 1)
{
ans = ans * a%m;
}
a = a * a%m;
b >>= 1;
}
return ans;
}
ll x[maxv], y[maxv], n, m, kk, u[maxv], r[maxv], dp[maxv][maxv], c[maxv][maxv], v[maxv];
void init()
{
for (ll i = 0; i < maxv; i++)
{
c[i][0] = c[i][i] = 1;
for (ll j = 1; j < i; j++)
{
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
}
ll play(ll uu, ll rr)
{
for (ll i = 1; i <= n + 1; i++)
{
y[i] = 0;
for (ll j = 1; j <= i; j++)
{
y[i] = (y[i] + quick_pow(i - j, rr - 1, mod)*quick_pow(j, n - rr, mod) % mod) % mod;
}
if (uu == i)
{
return y[i];
}
}
ll ans = 0;
for (ll j = 1; j <= n + 1; j++)
{
ll fz = y[j], fm = 1;
for (ll i = 1; i <= n + 1; i++)
{
if (i == j)
continue;
fz = (fz * (uu - i) % mod + mod) % mod;
fm = (fm * (j - i) % mod + mod) % mod;
}
ll qfm = quick_pow(fm, mod - 2, mod);
ll now = fz * qfm%mod;
ans = (ans + now) % mod;
}
return ans;
}
int main()
{
init();
scanf("%lld %lld %lld", &n, &m, &kk);
for (ll i = 1; i <= m; i++)
{
scanf("%lld", &u[i]);
}
for (ll i = 1; i <= m; i++)
{
scanf("%lld", &r[i]);
}
dp[0][n - 1] = 1;
for (ll i = 1; i <= m; i++)
{
ll gg = play(u[i], r[i]);
for (ll j = kk; j <= n; j++)
{
for (ll k = j; k <= n; k++)
{
if (k - j > r[i] - 1 || n - k - 1 < r[i] - 1 - k + j)
{
continue;
}
dp[i][j] = (dp[i][j] + dp[i - 1][k] * c[k][k - j] % mod * c[n - k - 1][r[i] - 1 - k + j] % mod) % mod;
}
dp[i][j] = dp[i][j] * gg%mod;
}
}
printf("%lld\n", dp[m][kk]);
return 0;
}