P5999 [CEOI2016] kangaroo的TJ
[CEOI2016] kangaroo
其实就是给你一个
我们若是依次考虑每
设
先考虑
很明显,他们要么是会加入最左边/最右边的块,要么是单独在最左边/最右边作为一个块,所以:
其他情况下,我们分情况考虑:
- 若他把两个块合并起来,由于之前块的每一个数都比他小,所以明显可以,则
(之前的 个块中有 个空隙,可以填入任意一个)。 - 他加入一个块,那么此时他旁边的那个肯定小于它,但未来加入的肯定大于他,不合法。
- 若他单独开一个块,很明显接下来插入他两边的都比他大,则有
个位置,但是需要注意的是,若他比 大,则不能放到最左边(同 靠一起),比 大同理,则
注意到这样子我们构造出来的每一段都是如:小->大->小->大->小 这样的形式的,所以保证了dp式子的正确性(主要是第一个情况)。
初始状态为
#include<bits/stdc++.h> #define int long long #define ull unsigned long long using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if (ch=='-') f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48); return x*f; } const int N=2e3+5,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7; int n,s,t; int f[N][N]; signed main(){ n=rd(),s=rd(),t=rd(); f[1][1]=1; for(int i=2;i<=n;i++){ for(int j=1;j<=i;j++){ if(i==s||i==t) f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod; else{ f[i][j]+=f[i-1][j+1]*j%mod; f[i][j]+=f[i-1][j-1]*(j-(i>s)-(i>t))%mod; f[i][j]%=mod; } } } printf("%lld\n",f[n][1]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!