见过山顶的云霄,看过谷底的幽静,二者都令我怀念。|

LittleMoMol

园龄:2年8个月粉丝:7关注:2

P5999 [CEOI2016] kangaroo 蓝 题解

前言

有些题目照常 DP 不是很好做,感觉像是区间 DP,但是怎么设状态都不好转移,那么可以考虑一种维护块儿的 DP,就是这道题要用到的知识点。

背景分析

如果每次跳跃的点的编号形成一个序列的话,那么这个序列满足“波浪形”,即 a1<a2, a2>a3, a3<a4 或者 a1>a2, a2<a3, a3>a4

那么转化问题,求 1n 的所有排列中,满足该排列构成的序列是“波浪形”的排列有几个。

前置知识

该题这种 DP 维护的是一个个块,可以设状态 fi,j 表示填好了 1n 中的数,共有了 j 个块。

比如:f7,3 表示前 7 个数中共有 3 个块,这 3 个块里面的信息可以是 [1][2][3,4,5,6,7],也可以是 [4,1,5][2,3][6,7],怎样都行。

每新填一个数,这个数可以开一个新块儿,也可以根据这个数合并之前的块儿,我们具体分析。

加新块

如果加数字 i 之前已经有了 j1 个块,这些块儿会形成 j 个空,那么这个数字 i 单独形成的块儿就可以查到这 j 个空中的一个,所以 fi,j=fi1,j1×j

合并块

如果加数字 i 之前已经有了 j+1 个块,这些块儿会形成 j+2 个空,但是,如果你把数字 i 放到最前面或者最后面,那么因为最前(后)面没有块儿,就无法合并,所以实际上合法的空只有 j 个。

所以方程是 fi,j=fi1,j+1×j

这道题目

我们依旧是填数,从 1 填到 n,那么对于当前数 i,之前填的数都比这个数小,之后填的数都比这个数大,那么加新块、合并块这两个操作都是合法的,无论你放在哪里(此时还不考虑 s,t 的影响

考虑到 st,由于最终的块一定合并成了一个,且以 s 开头、以 t 结尾,那么他会影响到加新块的操作。

为什么?

如果 s 已经填好了,那么 s 所在的位置必然是第一个块的首部,此时你若加新块,必然不能加到 s 所在块的前面去,因为这样做会使最后合并的块无法满足 s 开头

如果 t 已经填好了,那么 t 所在的位置必然是最后一个块的尾部,此时你若加新块,必然不能加到 t 所在块的后面去,因为这样做会使最后合并的块无法满足 t 结尾

那么加新块的状态转移方程为:fi,j=fi1,j1(j[i>s][i>t])

[] 表示如果中括号内条件满足返回 1,否则返回 0

i>s 满足,则其表示填 i 的时候,s 已经填好了,那么第一个块的前面就不能再放了,所以要减一,i>t 同理。

对于合并块的操作无影响。

那么对于 i=s,i=t 的情况,该怎么办呢?我们拿 i=s 作说明,i=t 同理。

i=s,如果要加新块,必然要加到最前面,所以只有一个位置合法,转移方程 fi,j=fi1,j1×1;如果要合并块,你也只能把 s 放到第一个块的最前面,这样做块数是不变的,且只有一个合法位置,转移方程 fi,j=fi1,j

Code

#include <iostream>
#include <cstring>

using namespace std;

typedef long long LL;
const LL N = 2e3 + 10;
const LL mod = 1e9 + 7;

LL n, s, t;
LL f[N][N];

int main()
{
    cin >> n >> s >> t;
    f[1][1] = 1;
    for (LL i = 2; i <= n; i ++ )
    {
        for (LL j = 1; j <= i; j ++ )
        {
            if (i == s || i == t)
            {
                f[i][j] = (f[i][j] + f[i - 1][j - 1] + f[i - 1][j]) % mod;
                continue;
            }
            f[i][j] = (f[i][j] + f[i - 1][j - 1] * (j - (i > s) - (i > t))) % mod;
            f[i][j] = (f[i][j] + f[i - 1][j + 1] * j) % mod;
        }
    }
    cout << f[n][1] << endl;
    return 0;
}

尾声

自己做不会,看题解也挺蒙的,搞了一下午才明白。

完结撒花!

本文作者:LittleMoMol

本文链接:https://www.cnblogs.com/LittleMoMol-kawayi/p/solution_LuoGu_P5999.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   LittleMoMol  阅读(28)  评论(0编辑  收藏  举报
*/
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示