You are given five integers nn, ii, jj, xx, and yy. Find the number of bitonic permutations BB, of the numbers 11 to nn, such that Bi=xBi=x, and Bj=yBj=y. Since the answer can be large, compute it modulo 109+7109+7.
A bitonic permutation is a permutation of numbers, such that the elements of the permutation first increase till a certain index kk, 2≤k≤n−12≤k≤n−1, and then decrease till the end. Refer to notes for further clarification.
Input
Each test contains multiple test cases. The first line contains a single integer tt (1≤t≤1001≤t≤100) — the number of test cases. The description of test cases follows.
The only line of each test case contains five integers, nn, ii, jj, xx, and yy (3≤n≤1003≤n≤100 and 1≤i,j,x,y≤n1≤i,j,x,y≤n). It is guaranteed that i<ji<j and x≠yx≠y.
Output
For each test case, output a single line containing the number of bitonic permutations satisfying the above conditions modulo 109+7109+7.
Example
input
7
3 1 3 2 3
3 2 3 3 2
4 3 4 3 1
5 2 5 2 4
5 3 4 5 4
9 3 7 8 6
20 6 15 8 17
output
0
1
1
1
3
0
4788
题意: 需要构造一个长度为n的排列,要求这个排列必须先增后减,且a[x] = vx, a[y] = vy,问这样的排列有多少个。
分析: 因为排列必须先增后减,所以构造的方法肯定是先选择一个最大值的位置,然后依次将n~1填入该位置两侧,数字放置的位置必须连续,否则构造不出来合法的排列。设dp[i][j]表示按这种方法填完区间[i, j]的合法方案数,如果不考虑两个数的限制,那递推方式就是dp[i][j] = dp[i+1][j]+dp[i][j-1],考虑最后一个要填的数字n-len+1放最左边还是最右边即可。加上这两个数的限制其实就是考虑一下n-len+1恰好等于vx或者vy的时候,假设n-len+1恰好等于vx,那么如果x等于i,此时vx只能放在i这个位置了,dp[i][j] = dp[i+1][j],若x等于j,则dp[i][j] = dp[i][j-1],如果x既不等于i也不等于j就说明不存在合法方案,直接dp[i][j] = 0。dp数组初始化的时候要看下vx或vy是否等于n,等于n的时候要特殊处理一下,然后因为数组必须先增后减,所以n这个数字肯定不能放在a[1]或a[n]处,要设置dp[1][1] = dp[n][n] = 0。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define int long long
using namespace std;
int dp[105][105];
const int mod = 1e9+7;
signed main(){
int T;
cin >> T;
while(T--){
int n, x, y, vx, vy;
scanf("%lld%lld%lld%lld%lld", &n, &x, &y, &vx, &vy);
if(vx != n && vy != n)
for(int i = 1; i <= n; i++){
if(i != x && i != y) dp[i][i] = 1;
else dp[i][i] = 0;
}
else if(vx == n){
for(int i = 1; i <= n; i++){
if(i == x) dp[i][i] = 1;
else dp[i][i] = 0;
}
}
else{
for(int i = 1; i <= n; i++){
if(i == y) dp[i][i] = 1;
else dp[i][i] = 0;
}
}
dp[1][1] = dp[n][n] = 0;
for(int len = 2; len <= n; len++){
for(int l = 1; l+len-1 <= n; l++){
int r = l+len-1;
//考虑把n-len+1放哪个位置
if(n-len+1 == vx){
if(l == x) dp[l][r] = dp[l+1][r];
else if(r == x) dp[l][r] = dp[l][r-1];
else dp[l][r] = 0;
}
else if(n-len+1 == vy){
if(l == y) dp[l][r] = dp[l+1][r];
else if(r == y) dp[l][r] = dp[l][r-1];
else dp[l][r] = 0;
}
else dp[l][r] = (dp[l+1][r]+dp[l][r-1])%mod;
}
}
// for(int i = 1; i <= n; i++, putchar('\n'))
// for(int j = 1; j <= n; j++)
// cout << dp[i][j] << " ";
printf("%lld\n", dp[1][n]);
}
return 0;
}