地精部落 bzoj-1925 Sdoi-2010

题目大意:给你一个数n和模数p,求1~n的排列中满足每一个数的旁边两个数,要么一个是边界,要么都比它大,要么都比它小(波浪排列个数)

注释:$1\le n\le 4200$ , $1\le p\le 10^9$。

想法:神题!这题标签给的是dp,但是一个没有动态性的dp应该叫递推吧qwq。先证几个引理:

引理1:对于任意的一个波动序列,将其中的第i个数a[i]离散成坐标系中的一个点(i,a[i]),这样所构成的波动离散点集关于任意的一条平行于x轴的直线对称后的(i,a'[i]),a'序列仍是波动序列。

  证明:假设那条直线是y=b。那么对于任意的$i\in [2,n-1]$,都有min(b-a[i-1],b-a[i+1])>b-a[i]或max(b-a[i-1],b-a[i+1])<b-a[i],反转之后,显然有max(a[i-1],a[i+1])<a[i]or min(a[i-1],a[i+1])>a[i],证毕。

引理2:如果交换波动序列中两个位置不相邻但是单调性相邻的数(单调性相邻,就是说将原波动序列上的所有数按照权值排序后相邻的两个数),交换后的序列仍是波动序列,

  证明:显然。

然后,我们设

  递推状态:dp[i][j],表示1~i的排列中,第一位为j且为山峰的方案数。

  转移:dp[i][j]=dp[i][j-1]+dp[i-1][i-j+1]。

为什么呢?首先,我们对dp[i][j]的所有方案进行一个分划:由于j是第一位且为山峰,所以,j-1可以处在第二位。但是dp[i][j-1]中,j是不可能处在第二位的,所以,我们对于dp[i][j-1]中的每一种排列都将j和j-1交换。j-1是山峰交换后j自然也是山峰,由引理2可知交换后仍是波动序列。此时,我们处理好了j-1不在第二位的情况。如果j-1钦定在第二位呢?我们对于这样的i-1个数:1,2,...j-1,j+1,...,i。将它们所有的数都变成关于y=0对称后向上平移i个单位的数,即变成:i-1,i-2,...,i-j+1,i-j-1,...,0.然后,我们有:dp[i][i-j+1]是原序列从小到大排序,第i-j+1个数作为第一个数且为山峰的方案数。这样的方案数在将所有数都恢复到原来的样子,仍然是波动序列只不过第一个数是j-1且为山谷,将j放在j-1之前,恰满足题意。

最后,附上丑陋的代码... ...

#include<bits/stdc++.h>
#define N 5010
using namespace std;
int dp[2][N];
int n,mod;
int main()
{
scanf("%d%d",&n,&mod);
dp[0][2]=1;
for(int i=3;i<=n;i++)
{
for(int j=2;j<=i;j++)
{
dp[i&1][j]=(dp[i&1][j-1]+dp[(i-1)&1][i-j+1])%mod;
}
}
int ans=0;
for(int j=2;j<=n;j++)
{
ans=(ans+dp[n&1][j])%mod;
}
printf("%d",(ans<<1)%mod);
}

小结:对于波动序列,有一些小的引理或性质有待挖掘... ...

最新文章

  1. ie11浏览器和chrome浏览器对于bgsound和background的一些区别
  2. mysql自动添加最后修改时间
  3. How to create water Ripple effect using HTML5 canvas
  4. linux tricks 之VA系列函数.
  5. scapy 安装及简单测试
  6. UVa 699 (二叉树) The Falling Leaves
  7. 用CURL来实现file_get_contents函数:curl_file_get_contents
  8. table不能遗露了tbody
  9. Traceroute原理介绍
  10. 获取文件数据流+叠加byte数组(给byte数组加包头包尾)
  11. 关于JVM的ClassLoader(转)
  12. SVM阅读资料
  13. 会话跟踪技术之——cookie
  14. System V IPC 之共享内存
  15. 企业IT管理员IE11升级指南【13】—— 如何把IEMP迁移到GPP
  16. linux下启动和关闭tomcat服务的方式
  17. Win10系列:VC++绘制文本
  18. 给VMware下的Linux扩容磁盘空间到根分区(以centos7.0为例)
  19. c# axPageLayoutControl 加数据框
  20. [整理]前端模块化开发AMD CMD

热门文章

  1. 慕课网3-13编程练习:采用flex弹性布局制作页面主导航
  2. strupr函数
  3. mysql中类型转换
  4. Oracle(一)
  5. ACM_三元一次函数解法(克莱姆法则)
  6. ACM_题目这么难,来局愉快的昆特牌吧
  7. 什么是mycat?
  8. [转]Android ListView的Item高亮显示的办法
  9. 通过HTTP协议实时获取微信聊天记录
  10. Java系列学习(十一)-内部类