BZOJ 1925 [Sdoi2010]地精部落

抖动序列DP

思维难度好大- -,我就发一个比较详细的题解吧

记f[i][j]表示长度为i(可以理解为序列是1~i的排列),首项取值为[1,j]的第一段为下降抖动序列方案数。(这个方程还真是很难想出来,要考虑到长度为i的序列可以由长度为i-1的序列通过首项的关系转移过来)

方程:f[i][j]=f[i][j-1]+f[i-1][i-j]

f[i][j-1]好理解,这可以直接求出首项为[1,j-1]的方案数,于是接下来要考虑的是如何求首项为j的方案数。

假设首项为j,依所设第一段下降,第二段必上升,于是只需要算出首项取值为[1,j-1],长度为i-1,且第一段上升的序列的方案数即可, 记作g[i-1][j-1]。

发现一个性质,对于长度为i的数列,如果使数列的每一项ai变为i-ai+1,都可以得到每一段状态(上升或下降)恰好相反的一个数列,并且他们一定是一一对应的,于是有f[i][j]=g[i][i-j+1],于是上面的g[i-1][j-1]=f[i-1][i-j],方程就不难理解了。

有一个不好理解的地方,对于g[i-1][j-1]的任一序列里面的数和f[i][j]的首项相等,即含有数字j怎么办?我们只需要使g[i-1][j-1]中大于等于j的数字全部加一再加上新首项j,肯定能形成合法序列,并且也是一一对应的。

注意,f[i][j-1]≠g[i][j-1],因为即使具有对称性,但f中首项虽取值[1,j-1],但取上一段所述的对称操作后不一定会小于j&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值