sgu 544
題意:
有两个长度为n的序列,两个序列中没有重复数字。可以对第一个序列任意排序,求有多少种排列使得第一个序列对应位置的数大于第二个序列的个数比对应位置的数小于第二个序列的个数多m。
解法:
第一个比第二个多m,若假设第一个大的有x个,则有下式:
\(x-(n-x)=m => 2*x=n+m\)
若\((n+m)\)为奇数,答案为0,为偶数,则计算第一个大的有\((n+m)/2\)个的排列数
设两个数组为\(u,v\), 先对两序列排序。令\(h[i]\)表示第二个序列中比\(u[i]\)小的数字个数。
令 \(dp[i][j][k]\) 表示第一个序列中前\(i\)个数字有\(j\)个未被分配,已分配的有\(k\)个比第二个序列大的种类数。
转移方程:
\(dp[i+1][j-x+1][k] += dp[i][j][k]*A(h[i+1]-h[i],x)*C(j,x)\)
\(dp[i+1][j-x]k+1] += dp[i][j][k]*A(h[i+1]-h[i],x)C(j,x)(h[i+1]-i+j-x)\)
其中\(x\)为这次分配的数字个数。\(0=<x<=min(j,h[i+1]-h[i])\)。
trick: 表面上看这个算法复杂度是\(O(n^4)\),但是,最后一层循环的\(\sum_1^n(h[i+1]-h[i])=n\) ,所以实际复杂度为\(O(n^3)\)。