【ybt金牌导航1-2-6】【luogu P2467】地精部落

地精部落

题目链接:ybt金牌导航1-2-6 / luogu P2467

题目大意

有一个排列,要使得每个位置要么都比两边高,要么比两边低。
而且一定要以一高一低的方式排列。
两边的只用比旁边的那个高或低就可以。
给出排列的长度 n 和模数,要你求出排列的种数在模数取模意义下的值。

思路

我们考虑设 f i , j f_{i,j} fi,j 为前 i i i 个数的排列,最后一个数是高的,然后是 j j j 会有的方案数。

那我们可以发现有几个特点:

  1. 高低高低和低高低高这两种形状的类型种数都是相同的。
    因为你可以把 a 1 , b 1 , a 2 , b 2 , a 3 a_1,b_1,a_2,b_2,a_3 a1,b1,a2,b2,a3 看成 n − a 1 + 1 , n − b 1 + 1 , n − a 2 + 1 , n − b 2 + 1 , n − a 3 + 1 n-a_1+1,n-b_1+1,n-a_2+1,n-b_2+1,n-a_3+1 na1+1,nb1+1,na2+1,nb2+1na3+1
    那这个既是另一种类型了。
  2. 如果一个排列已经是满足的了,而且 i i i i + 1 i+1 i+1 不相邻。那我们可以把他们互换,还是合法的。就因为他们不相邻,那它们就算交换了,它们还是原来的高低状态,就没有问题。

那我们可以求以高结尾的方案数,然后再输出乘 2 2 2 即可。
那怎么求高结尾的呢?
考虑根据上面的特点搞转移方程。
f i , j = f i , j − 1 + f i − 1 , n − j + 1 f_{i,j}=f_{i,j-1}+f_{i-1,n-j+1} fi,j=fi,j1+fi1,nj+1
为什么呢?
按相不相邻来分开,不相邻的就可以交换直接形成新的波动,那就是把 j j j j − 1 j-1 j1 交换所能有的方案数,就是 f i , j − 1 f_{i,j-1} fi,j1

那我们考虑如果相邻,是怎么样的。
那它就变成了 前 i − 1 i-1 i1 个数的排列, j − 1 j-1 j1 是最后一个,且是山谷的情况。因为这样你就可以直接让 j + 1 ∼ i − 1 j+1\sim i-1 j+1i1 的区间的数都加一(因为是相对的关系,加了之后还是满足高低关系),然后再在最后的位置把 j j j 插进去。
那你由前面可以知道,你前面是山谷,那你要把山谷改成山峰,那第二位就要变成 ( i − 1 ) − ( j − 1 ) + 1 (i-1)-(j-1)+1 (i1)(j1)+1,即 i − j + 1 i - j+1 ij+1。那就可以从 f [ i − 1 ] [ i − j + 1 ] f[i-1][i-j+1] f[i1][ij+1] 转移过来。

然后你就得到了转移方程。

当然,两个 3500 3500 3500 的数组会炸空间,那我们观察到 i i i 这一维只会涉及前面的那一个,那就可以用滚动数组解决空间问题。

代码

#include<cstdio>

using namespace std;

int n, p, f[3][4201], ans;

int main() {
	scanf("%d %d", &n, &p);
	
	f[2 & 1][2] = 1;//一开始最后为高的只有这一种,初始化
	for (int i = 3; i <= n; i++)
		for (int j = 1; j <= i; j++) {
			f[i & 1][j] = (f[i & 1][j - 1] + f[(i - 1) & 1][i - j + 1]) % p;//dp
		}
	
	for (int i = 1; i <= n; i++)
		ans = (ans + f[n & 1][i]) % p;//最后可能以不同的数字结束
	
	printf("%d", (ans * 2) % p);
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值