题意

给一段程序:

int qsort(int L, int R) {
	if (L >= R) return 0;
	int i = L, j = R;
	int x = Random.Next();
	int x0 = A[x];
	assert(L <= x && x <= R);
	while (i < j) {
		while (A[i] < A[x]) i++;
		while (A[j] > A[x]) j--;
		if (i <= j) {
			if (i == x) x = j;
			else if (j == x) x = i;
			swap (A[i], A[j]);
			i++; j--;
		}
	}
	swap(A[x], A[x0]);
	return R - L + qsort(L, x0 - 1) + qsort (x0 + 1, R);
}

其中,在最后一行先运行 qsort(L, x0 - 1) 再运行 qsort (x0 + 1, R)。由于随机数不取模,x 可能越界,排序会被 assert(L <= x && x <= R); 终止,此时排序结束且没有返回值。

给定长度 $N$ 和可能用到的前 $N$ 个随机数。对于所有的长度为 $N$ 的排列,求 qsort(1,N) 可能的最大值是多少,并输出其中一个最大的排列。

$n\leq 50,1\leq\text{Random}_i\leq N$

口胡

看到这种题慌了。但其实不要慌。

多分析多模拟。快排就是随机选个数,把比它小的放左边,大的放右边。

有点像记忆化搜索,然后对于 $L,R$ 状态用 DP 存储,进而想到区间 DP,但是只有 $L,R$ 维护不了随机数,那就加状态,设 $f_{L,R,k,l}$ 表示处理 $[L,R]$ 时,使用了 $k$ 个随机数,下标从 $l$ 开始。转移时枚举排序后位置、左边部分需要的随机数个数。

还原排列就考虑选取排序前后数的位置手玩可以得到。

EOF

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。

博客信息