拿到这道题秒懂题意:波动序列。

然鹅不会打。想了一节课,想打纯组合数学,结果找不到规律。

想的是先假设拍出一个序列,然后交换其中的元素求组合,

无奈没啥规律可循,显然不能一口气求出来(我说的是我没办法,网上大佬们有的是办法……)

然后想dp,挨个插入,妄图一维dp走起,结果摔倒在地

然后我就不是人了。

^废话^


称n个数组成的波动数列为n阶波动数列。

我们设f[i][j]表示一个i阶波动数列首个数是j且为山峰的排列种数

然后推一下状态转移方程。

仔细考虑一下,波动序列似乎有这么几个性质


性质一:一个波动序列的连续子序列仍然是波动序列。

性质二:若使一个波动序列排列中大于等于x的元素全部+1,序列仍然满足波动。

性质三:若一个波动序列的排列中x与x+1不相邻,那么交换二者,序列仍然满足波动。

性质四:一个[1,x]的波动序列一定可以对应到[y-x+1,y]的一个波动序列。


其实都是一些十分显然的性质。我们主要用到了性质一、三和四来搞我们的状态转移方程。

简单证明性质三(因为某大佬问我的时候在这个性质上稍微犹豫了一下~)

1.若x为波谷,由于x与x+1不相邻,则x两侧的波峰最低为x+2和x+3,交换后仍然满足波动序列。

2.若x为波峰,x两侧的波谷小于x,则必定小于x+1。所以交换后仍然满足波动序列。

证毕。

(^自己证哒^,有不当的地方请多多海涵并评论指出~谢谢大家~)

所以根据性质一,我们可以进行状态转移。(没错性质一是最费的……)

根据性质三,f[i][j]+=f[i][j-1]。(把+1和-1倒个个儿还是一样的……我是不是证翻了QAQ)这好说。

但我们只考虑了性质三中x与x+1不相邻的状态。

于是尝试把j掐掉。

我们发现,把波动序列最左边的j掐掉之后剩下了一个i-1阶的波动序列。

但是我们不能直接转移,现在最左边的变成了j-1。一切是那么顺利,可是j-1是波谷啊QAQ!!

波谷!!

那怎么办?没关系我们有性质四

回顾一下性质四:一个[1,x]的波动序列一定可以对应到[y-x+1,y]的一个波动序列。

这是啥?这是救世主!

于是我们把所有的序列对应到i-j+1上,发现这东西瞬间变波峰。

(这需要证明吗QAQ,我懒啊~)

然后我们得到了另外一个状态转移:

f[i][j]+=f[i-1][(i-1)-(j-1)+1]。(别问我为什么变成i-1和j-1了 /糊脸)

完结撒花~

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
#define rint register int
using namespace std;
ll n,mod,f[][];
signed main()
{
ll now=;
scanf("%lld %lld",&n,&mod);
f[now][]=;
for(rint i=;i<=n;i++)
{
now^=;
for(rint j=;j<=i;j++)
f[now][j]=(f[now][j-]+f[now^][i-j+])%mod;
}
ll ans=;
for(rint i=;i<=n;i++)
ans=(ans+f[now][i])%mod;
ans=(ans*%mod+mod)%mod;
printf("%lld\n",ans);
return ;
}

全靠思维量撑起……

「题解」:[组合数学][DP]:地精部落的更多相关文章

  1. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  2. 「TJOI2015」组合数学 解题报告

    「TJOI2015」组合数学 这不是个贪心吗? 怎么都最小链覆盖=最大点独立集去了 注意到一个点出度最多只有2,可以贪心一下出度的去向 按读入顺序处理就可以,维护一个\(res_i\)数组,表示上一行 ...

  3. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  4. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  5. 「动态规划」-数位dp专题

    数位dp,今天学长讲的稍玄学,课下花了一会时间仔细看了一下,发现板子是挺好理解的,就在这里写一些: 数位dp主要就是搞一些在区间中,区间内的数满足题目中的条件的数的个数的一类题,题目一般都好理解,这时 ...

  6. 「笔记」数位DP

    目录 写在前面 引入 求解 特判优化 代码 例题 「ZJOI2010」数字计数 「AHOI2009」同类分布 套路题们 「SDOI2014」数数 写在最后 写在前面 19 年前听 zlq 讲课的时候学 ...

  7. 「题解」:[组合数学]:Perm 排列计数

    题干: Description称一个1,2,…,N的排列P1,P2…,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,…N的排列中有多少是Magic的,答 ...

  8. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  9. 「总结」插头$dp$

    集中做完了插头$dp$ 写一下题解. 一开始学的时候还是挺蒙的. 不过后来站在轮廓线$dp$的角度上来看就简单多了. 其实就是一种联通性$dp$,只不过情况比较多而已了. 本来转移方式有两种.逐行和逐 ...

随机推荐

  1. C#面向对象通信

    面向对象通信编程: 看起来像是调用本地的函数,就得到了结果: 实际上参数是传递到了远程机器上了,而函数也是在远程机器上运行的.

  2. USACO2007 Protecting the Flowers /// 比值 前缀和 oj21161

    题目大意: 有N (2 ≤ N ≤ 100,000) 头牛偷吃花 将牛赶回牛棚需Ti minutes (1 ≤ Ti ≤ 2,000,000) 每头牛每分钟能吃Di (1 ≤ Di ≤ 100) 朵花 ...

  3. JS对象 substring() 方法用于提取字符串中介于两个指定下标之间的字符。

    提取字符串substring() substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法: stringObject.substring(starPos,stopPos)  参 ...

  4. 【bug】vue同一组件使用

    vue使用同一个组件渲染,进行切换过程中会存在数据保存的情况. 比如路由切换,进行渲染的页面来自同一个组件,这个时候,要在监听路由的时候,将数据重新初始化

  5. Linux tee命令使用详解分享

    tee命令主要被用来向standout(标准输出流,通常是命令执行窗口)输出的同时也将内容输出到文件,下面是tee的man 信息 read from standard input and write ...

  6. 剑指Offer-14:输入一个链表,输出该链表中倒数第k个结点。

    题目描述: 输入一个链表,输出该链表中倒数第k个结点.例如有一个链表有六个节点1,2,3,4,5,6.则它的倒数第二个节点为5 节点定义如下: public class ListNode { int ...

  7. LUOGU P3048 [USACO12FEB]牛的IDCow IDs(组合数)

    传送门 解题思路 组合数学.首先肯定是要先枚举位数,假如枚举到第\(i\)位.我们可以把第一位固定,然后那么后面的随意放\(1\),个数就为\(C_{i-1}^{k-1}\).然后每次枚举时如果方案\ ...

  8. POJ 3134 - Power Calculus

    迭代加深 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<al ...

  9. layui点击按钮自动刷新页面问题

    问题 <button class="layui-btn layui-btn-primary" onclick="findData()">查询< ...

  10. Requests+Excel接口自动化测试(Python)

    一.框架结构:  工程目录 二.Case文件设计 三.基础包 base 3.1 封装get/post请求(runmethon.py) import requests import json class ...