Problem Description
For a given permutation a1,a2,⋯,an of length n, we defined the neighbor sequence b of a, the length of which is n−1, as following:
.
For example, the neighbor sequence of permutation 1,2,3,6,4,5 is 0,0,0,1,0.
Now we give you an integer n and a sequence b1,b2,⋯,bn−1 of length n−1, you should calculate the number of permutations of length n whose neighbor sequence equals to b.
To avoid calculation of big number, you should output the answer module 109+7.
Input
The first line contains one positive integer T (1≤T≤50), denoting the number of test cases. For each test case:
The first line of the input contains one integer n,(2≤n≤5000).
The second line of the input contains n−1 integer: b1,b2,⋯,bn−1
There are no more than 20 cases with n>300.
Output
For each test case:
Output one integer indicating the answer module 109+7.
Sample Input
2
3
1 0
5
1 0 0 1
Sample Output
2
11
题意:
给一个只包含0、1,长度维n - 1的数组b,
b[i] = 1 表示a[i] > a[i + 1]
b[i] = 0 表示a[i] < a[i + 1]
a数组是1~n的一个排列,问有多少种a数组。
思路:
代码:
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 5e3 + 5;
const ll mod = 1e9 + 7;
ll dp[N][N];
ll x[N], y[N];
int T, n, a;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--)
{
cin >> n;
for (int i = 0; i <= n; ++i)
{
for (int j = 0; j <= n; ++j)
{
dp[i][j] = 0;
if (i + j == n - 1)
dp[i][j] = 1;
}
}
for (int i = 2; i <= n; ++i)
{
y[0] = dp[n - i + 1][0], x[0] = dp[0][n - i + 1];
for (int r = 1; r <= n - i + 1; ++r)
{
y[r] = (dp[n - i + 1 - r][r] + y[r - 1]) % mod;
x[r] = (dp[r][n - i + 1 - r] + x[r - 1]) % mod;
}
cin >> a;
if (a)
{
for (int l = 0, r = n - i; l <= n - i; ++l, --r)
{
dp[l][r] = (dp[l][r] + y[n - i + 1] - y[r]) % mod;
}
}
else
{
for (int l = 0, r = n - i; l <= n - i; ++l, --r)
{
dp[l][r] = (dp[l][r] + x[n - i + 1] - x[l] + mod) % mod;
}
}
}
dp[0][0] = (dp[0][0] % mod + mod) % mod;
cout << dp[0][0] << endl;
}
return 0;
}