博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SDOI2010]地精部落
阅读量:6601 次
发布时间:2019-06-24

本文共 1159 字,大约阅读时间需要 3 分钟。

题目大意:

  若数列$\{A_i\}$为$1\sim n(n\le4200)$的一个排列,求满足对于任意$1<i<n$都有$A_i>A_{i-1}$且$A_i>A_{i+1}$或$A_i<A_{i-1}$且$A_i<A_{i+1}$的$\{A_i\}$的方案数。

思路:

  用$f[i][j]$表示$A$的前$i$项为$1\sim i$的排列,$A_1=j>A_2$的方案数。
  若$j-1\ne A_2$,则直接交换$j$和$j-1$,数列依然满足条件,贡献$f[i][j-1]$的方案数。
  若$j-1=A_2$,则贡献为$A$的前$i-1$项为$1\sim i-1$的排列,$A_1=j-1<A_2$的方案数。不难发现对于数列$A$,若将每一个$A_i$都替换成$n-A_i+1$,数列依然满足条件。则贡献的方案数等同于$f[i-1][i-j+1]$。
  则得出状态转移方程为$f[i][j]=f[i][j-1]+f[i-1][i-j+1]$。

1 #include
2 #include
3 inline int getint() { 4 register char ch; 5 while(!isdigit(ch=getchar())); 6 register int x=ch^'0'; 7 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 8 return x; 9 }10 const int N=4201;11 int f[2][N];12 int main() {13 const int n=getint(),mod=getint();14 f[0][2]=1;15 for(register int i=3;i<=n;i++) {16 for(register int j=2;j<=i;j++) {17 f[i&1][j]=(f[i&1][j-1]+f[!(i&1)][i-j+1])%mod;18 }19 }20 int ans=0;21 for(register int i=1;i<=n;i++) {22 (ans+=(f[n&1][i]*2)%mod)%=mod;23 }24 printf("%d\n",ans);25 return 0;26 }

 

转载于:https://www.cnblogs.com/skylee03/p/8621878.html

你可能感兴趣的文章
特别遍历树
查看>>
Java提升-工厂模式、工厂方法模式(二)
查看>>
测试 Modules
查看>>
Spring Cloud Finchley 正式发布,包含 4 个重大更新!
查看>>
深入解析java虚拟机-jvm运行机制
查看>>
CSS3简单动画效果与使用列表制作菜单
查看>>
MySQL远程登录
查看>>
一年代码提交mark 2056
查看>>
gRPC简介
查看>>
Linux 下修改oracle 的字符集:WE8ISO8859P1 修改为 AL32UTF8
查看>>
数据库查询语句执行顺序
查看>>
除法散列函数之散列值问题
查看>>
Android 常见问题之Assets文件大小限制
查看>>
Android广播:全局大喇叭是如何使用的!
查看>>
CentOS rsync配置
查看>>
除非你是BAT,前端开发中最好少造轮子
查看>>
JSP页面设置编码
查看>>
CSRF的攻击与防御
查看>>
合并dll到exe中(三)
查看>>
即时获取input输入框里的内容 IE/非IE皆可兼容
查看>>