版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82767527
题解:
先把
排序,
序列能被构造出来,则:
- 。
- 不存在 , ,或者 。这个应该很好理解,因为中位数每次最多挪动1。 我们也很好构造出 来对应 。
观察到 越靠后限制越强,我们从后往前DP,维护 表示第 个,可选数小等于 的有 个,大于 的有 个。 然后枚举下一个填什么即可。 时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=105, mod=1e9+7;
inline void add(int &x,int y) {x=(x+y>=mod) ? (x+y-mod) : (x+y);}
int n,a[N];
int f[N/2][N][N];
int main() {
n=rd();
for(int i=1;i<=2*n-1;i++) a[i]=rd();
sort(a+1,a+2*n);
f[n][1][0]=1;
for(int i=n-1;i>=1;i--) {
int al=(a[i]!=a[i+1]), ar=(a[2*n-i]!=a[2*n-i-1]);
for(int l=0;l<=2*n-1;++l)
for(int r=0;r+l<=2*n-1;++r) if(f[i+1][l][r]) {
int &t=f[i+1][l][r];
for(int dl=1;dl<=l+al;++dl) add(f[i][l+al-dl+1][r+ar+(dl>1)],t);
for(int dr=1;dr<=r+ar;++dr) add(f[i][l+al+1][r+ar-dr],t);
}
}
int ans=0;
for(int l=0;l<=2*n-1;++l)
for(int r=0;r+l<=2*n-1;++r)
add(ans,f[1][l][r]);
cout<<ans<<'\n';
}