题意:有一长度为n的排列(ai)来形成另一长度为n-1的序列(bi),形成方式为
现在直到b的序列,求存在多少个a满足b的条件。
思路:
根据图中的例子可以知道求数列a其实就是求数列c。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5010;
const int mod = 1e9+7;
int b[maxn];
int f[maxn][maxn],g[maxn][maxn];
/*f[i][j] 表示现在已经放到第 i 个数字,
而且第 i 个数字放的位置是 j,g[i][j]用于存放结果 */
void add(int &x,int y){
x+=y;
if(x>=mod)
x-=mod;
}
int main(){
int tcase;
cin>>tcase;
while(tcase--){
int n;
cin>>n;
for(int i=2;i<=n;i++){
cin>>b[i];
}
//初始化
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
f[1][1] = 1;//第一个数位置是1
for(int i = 2;i<=n;i++){//从第二个放起
for(int j = 1;j<i;j++){
//如果放的数是0,
//往 f[i + 1][k] (k > j) 转移
if(b[i] == 0){
add(g[i][j+1],f[i-1][j]);
}
//否则为1往 f[i + 1][k] (k ≤ j) 转移.
else{
add(g[i][j],f[i-1][j]);
}
}
if (b[i] == 0) {
for (int j = 1; j <= i; j++) {
add(f[i][j], f[i][j - 1]);
add(f[i][j], g[i][j]);
}
}
else {
for (int j = i; j >= 1; j--){
add(f[i][j], f[i][j + 1]);
add(f[i][j], g[i][j]);
}
}
}
int ans = 0;
for(int i = 1;i<=n;i++){
add(ans,f[n][i]);
}
cout<<ans<<endl;
}
return 0;
}