题目链接
题目大意
给你一个长度为n的数列,数列第i项可以取[li,ri],或者不取,使得最后取的数单调递增,问方案数,若所有数均不取不计入方案。
n≤500,li≤ri≤1e9
做法
我们先考虑这样一个问题,一个长度为n的数列,数列的每个数可以取[1,L],使得数列单调递增的方案数。那么这个答案显然是(Ln),当你选的数确定后,放的位置也自然就确定了。
接下来将问题改为一个长度为n的数列,数列的每个数可以取[1,L]或不取,使得最后取的数单调递增的方案数。
假设我们从这样一个数列中取n个数
前面总共有n个0。
我们将每种取数的方案如下映射到一个数列上。
如果取到第i个0,那么数列的第i位不取。
剩下取到的非0的数按照升序依次填入取的位即可。
这个映射显然是个双射,所以我们要求的答案即为(n+Ln)
那么知道了这个有什么用呢?
我们先将原先的值域离散成若干段左开右闭的区间,那么[li,ri]就表示若干段左开右闭的区间了。
考虑dp
用fi,j表示数列的前i项,第i项取在j这个区间中的方案数。
再枚举k,表示数列的第k项取,并且取的区间小于j。
也就是说数列的[k+1,i−1]这些要么不取,要么全部取在j这个区间中。
根据我们上面的结论,转移即为
L表示j这段开区间的长度,t表示[k+1,i]中有多少个位置,能取的范围是包括j这段开区间的,(如果不包括,显然只能不取)
对于后面这个式子我们用前缀和优化。
k从大往小枚举,组合数可以O(1)递推。
最后求答案并非是∞∑j=1fn,j,因为第n项可以不取,而fi,j中i这一项是必须取的。
所以我们考虑最后取的是哪一项,后面的都不取
代码
1 |
|