求解摆动数列的动态规划
题目描述
传说很久以前,大地上居住着一种神秘的生物:地精。
地精喜欢住在连绵不绝的山脉中。具体地说,一座长度为N的山脉H可分为从左到右的N段,每段有一个独一无二的高度Hi,其中Hi是1到N之间的正整数。
如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰。位于边缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边)。
类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷。
地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中。地精的酒馆不论白天黑夜总是人声鼎沸,地精美酒的香味可以飘到方圆数里的地方。
地精还是一种非常警觉的生物,他们在每座山峰上都可以设立瞭望台,并轮流担当瞭望工作,以确保在第一时间得知外敌的入侵。
地精们希望这N段山脉每段都可以修建瞭望台或酒馆的其中之一,只有满足这个条件的整座山脉才可能有地精居住。
现在你希望知道,长度为N的可能有地精居住的山脉有多少种。两座山脉A和B不同当且仅当存在一个i,使得Ai≠Bi。由于这个数目可能很大,你只对它除以P的余数感兴趣。
Inputs and Outputs examples
Inputs’ e.g. #1
1 | 4 7 |
Outputs’ e.g. #1
1 | 3 |
说明
【数据规模和约定】
对于20%的数据,满足N≤10;
对于40%的数据,满足N≤18;
对于70%的数据,满足N≤550;
对于100%的数据,满足3≤N≤4200,P≤1e9。
分析
首先认真读过题的选手一定知道题意的目的是波动数列.
我们首先要明白波动数列的性质:
在一个波动序列中,若$i$和$i+1$不相邻,那么将他们交换可以得到一个新的波动数列
我们设$dp_{i,j}$表示我们选用$1-n$这$n$个数,且第一个数为$j$的方案数.
那么显然答案就是$\sum_{i=1}^n dp_{n,i}$.
首先我们考虑$j$和$j-1$不相邻时的方案数,根据上面那条性质,我们可以推出在这种情况下,$j$作为序列头所有的方案数与$j-1$作为头的方案数相同.
然后如果$j$和$j-1$相邻呢?
我们假设$j$为凸出部分,那么显然与他相邻的$j-1$一定为凹进部分,后面的数一定在$[1,j-1) \bigcup (j,n]$上取值.
那么我们考虑求$i-1$个数,$j-1$为头,且$j-1$为山谷的方案数.
首先我们发现这$i-1$个数的取值不一定是$[1,i-1]$, 没关系,我们把他全$-1$就可以保证相对大小不变了.
那么我们可以列出dp的转移方程式
$$dp_{i,j} = dp_{i,j-1} + dp_{i-1,i-j+1}$$
代码
1 | /* Headers */ |