[AGC024E] Sequence Growing Hard
LXXX.[AGC024E] Sequence Growing Hard
首先,我们肯定能想到从第一个序列开始,依次加入一个新数得到下一个序列,同时还要保证字典序递增。我们如果让新数递增的话,就可以DP了。
我们首先观察往一个序列中加入一个不大于最大值的数会有多少种可能:
我们在中加入一个,
位置 | 结果 |
---|---|
开头 | |
第一个数后 | |
第二个数后 | |
第三个数后 | |
第四个数后 |
明显所有结果全都符合要求,但是有重复计算的地方。
我们可以强制要求加数必须加在连续一段相同的数的后面,在上例中就是你无法在第一个、第三个数后面添加。
我们可以设表示当前处理完成了前个串,计划往第个串里加入一个数,并且有个位置可以加入的方案数。
则可以转移到:
-
如果,可以转移到,它的意义是我们跳过第个位置不加。
-
如果,可以转移到,它的意义是第个数已经全部加完,可以尝试了。它有个位置可以填,因为没有任何一个数与相同,它可以直接加到任何数后面。
-
无论何时,都可以转移到,意义是我们在第个位置加入一个数。这共有种加法,因为我们还有一种在开头的加法是一直可以的。
复杂度。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,p,f[310][310][310];
//f[i][j][k]:we've finished constructing the first i sequences, now we're going to add the number j into the i+1-th sqeuence, and there're k places to add j into
int main(){
scanf("%d%d%d",&n,&m,&p),f[0][1][0]=1;
for(int i=0;i<=n;i++)for(int j=1;j<=m;j++)for(int k=i;k>=0;k--){
if(k)(f[i][j][k-1]+=f[i][j][k])%=p;//we decide not to add j to the k-th place, so we could add it to the (k-1)-th place.
else(f[i][j+1][i]+=f[i][j][k])%=p;//we have tried every place j could be added to, now it's time to try j+1, which could be added into any place
(f[i+1][j][k]+=1ll*f[i][j][k]*(k+1)%p)%=p;//we decide to add j to the k-th place, and there are (k+1) places for us to add (including the last one)
}
printf("%d\n",f[n][m+1][n]);//all n sequences've been constructed, and all number've been tried
return 0;
}
分类:
DP
, 数论——容斥与排列组合计数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?