问存在多少个长度为 n(2≤n≤5000) 的单调不减序列 a,满足 1≤ai≤n,且对于任意 k(1≤k<n),都有:对任意大小为 k 的子集 S 和大小为 k+1 的子集 T,满足 ∑x∈SAx<∑x∈TAx。答案对大质数 m 取模。
首先需要发现一个性质,就是如果 k=⌊2n⌋ 的时候满足了,那么其他的 k 都能满足。为什么呢?首先是对于每个 k,显然如果满足了 ∑i=1k+1ai≥∑i=n−k+1nai,就满足所有的 S 和 T 了。然后如果满足了 k=⌊2n⌋ 的情况,如果 k>⌊2n⌋,考虑到序列单调不降,左边加上一个较大的数,右边加上一个较小的数,那么不等式肯定仍然成立。否则,如果 k<⌊2n⌋,其实就是左边减去一个较小的数,右边加上一个较大的数,不等式也仍然成立。
那这个东西有什么用呢,我们考虑对一波式子。首先我们需要去掉一个单调性,我们构造一个差分数组 Δai=ai−ai−1,为了不让 Δa1 奇怪,我们就让 a0=1,这样子其实就是 ai=1+∑i=1nΔai,然后我们的式子就变成了:
i=1∑⌊2n⌋+1j=1∑iΔaj≥i=n−⌊2n⌋+1∑nj=1∑iΔaj
这个下取整感觉很难受,我们就直接将 n 奇偶讨论好了:
当 n 是奇数时,⌊2n⌋=2n−1,也就是原式就变成了:
i=1∑2n+1j=1∑iΔaj≥i=2n+1+1∑nj=1∑iΔaj
两边都加个 ∑i=12n+1∑j=1iΔaj 把右边给补一下:
2i=1∑2n+1j=1∑iΔaj≥i=1∑nj=1∑iΔaj
根据套路,我们需要把前面的 Σ 拆掉,于是我们拆掉它:
2i=1∑2n+1(2n+1−i+1)Δai≥i=1∑n(n−i+1)Δai
考虑我们将 ai 差分的目的,其实就是想把左边的式子减过去,然后合并起来:
i=1∑nciΔai≤0
其中
ci={i−2n−i+1i≤2n+1i>2n+1
同样地,我们来考虑 n 是偶数的情况:
i=1∑2nj=1∑iΔaj≥i=2n+2∑nj=1∑iΔaj
补一补:
2i=1∑2nj=1∑iΔaj≥i=1∑nj=1∑iΔaj−i=1∑2n+1Δai
拆个 Σ:
2i=1∑2n(2n−i+1)Δai≥i=1∑n(n−i+1)Δai−i=1∑2n+1Δai
写成 ∑ciΔai≤0 的形式,可以得到:
ci=⎩⎪⎪⎨⎪⎪⎧i−2n−in−i+1i≤2ni=2n+1i>2n+1
不难发现当 i=2n+1 时,n−i=2n−1=i−2,所以:
ci={i−2n−i+1i≤2n+1i>2n+1
综合奇偶两个式子,我们均可以得到:
i=1∑nciΔai≤0
其中
ci={i−2n−i+1i≤⌊2n⌋+1i>⌊2n⌋+1
我们回到题目,除了这个条件,我们再回过头来看看有什么缺的条件,仔细找了找好像只有 ∑Δai+1≤n 了。
于是我们考虑确定 a2∼an 的值,然后回过头来看看有多少个符合条件的 a1。
我们发现只有两个条件:
{a1≤n−1−∑i=2naia1≥∑i=2nciai
于是满足条件的 a1 个数就是:
max(0,n−i=2∑n(ci+1)ai)
我们令 fi 表示 ∑j=2n(cj+1)aj=i 的方案数,那么最终的答案就是 ∑i=0n−1(n−i)⋅fi。
我们最后要做的一件事情就是计算 fi 了,不难发现其实就是一个背包,第 i 个物品重量 ci,可以选 ai 个,直接大力 dp
过去即可。
于是复杂度 O(n2)。
代码