AT_abc237_f [ABC237F] |LIS| = 3 题解
AT_abc237_f [ABC237F] |LIS| = 3 题解
洛谷。
题意够简练了,不复述。
避坑
注意,洛谷的翻译有误,数列各项可以等于 ,不是 以下!!
而且 “最长增加部分列” 最好改为 “最长上升子序列”。
思路
胖头鱼教练:看题吧。
我:怎么动态维护最长上升子序列长度啊……
这时,注意到我们维护最长上升子序列长度并不关心序列所有数是多少。
那么我们可以把最长上升子序列长度分别是 、、 序列中的最大数维护出来,因为我们如果要更新最长上升子序列只看最大数。
那么想想算法。
这题我是从 dp 专题里看到的,所以当然是 dp 喽。
设 表示当前考虑到前 个数,长度为 的最大数是 , 的最大数是 , 的最大数是 的答案。
那么看看状态转移方程。
对于我们当前要插入的数字 ,考虑它可以插在哪里——
最后的答案显然是 。
AC CODE:
#include<bits/stdc++.h> using namespace std; #define ljl long long const ljl N=1001,mod=998244353; ljl n,m,f[N][15][15][15],ans; int main(){ ios::sync_with_stdio(0); cin>>n>>m; f[0][m+1][m+1][m+1]=1; for(ljl i=1;i<=n;++i) { for(ljl v=1;v<=m;++v) { for(ljl l1=1;l1<=m+1;++l1) { for(ljl l2=l1;l2<=m+1;++l2) { for(ljl l3=l2;l3<=m+1;++l3) { if(v<=l1) f[i][v][l2][l3]=(f[i][v][l2][l3]+f[i-1][l1][l2][l3])%mod; else { if(v<=l2) f[i][l1][v][l3]=(f[i][l1][v][l3]+f[i-1][l1][l2][l3])%mod; else if(v<=l3) f[i][l1][l2][v]=(f[i][l1][l2][v]+f[i-1][l1][l2][l3])%mod; } } } } } } for(ljl i=1;i<=m;++i) for(ljl j=1;j<=m;++j) for(ljl k=1;k<=m;++k) ans=(ans+f[n][i][j][k])%mod; cout<<ans<<'\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现