[NOI 2001] 陨石的秘密 题解
思路
首先我们发现可以搜索,但是明显会TLE,因为组合数学的结果是以指数倍增长的,结果会很大,明显不行。
由于不要输出路径,那么考虑DP。
令为深度,{}
对,[]
对,()
对的结果。
我们发现这样很难得出结果。
我们令为深度小于等于,{}
对,[]
对,()
对的结果,貌似可以好一点得到结果。
我们利用{}[]()
将字符串进行分割。令A
B
,那么就有三种情况:{A}B
[A]B
(A)B
,当然A
B
也可能是空串。不难证明这种DP方式是不重不漏的。
DP式如下:
初值:(空串深度为只有种可能)
细节
得出最后的 结果是。
但是,如果这么做,其实是错误的,因为有可能会为,那么我们就可以发现以下结论:
结果 | 解释 | ||
---|---|---|---|
都为 | 空串深度为只有种可能 | ||
都为 | 不为 | 空串不可能深度为 | |
不都为 | 非空串的深度一定大于等于 | ||
最后注意精度问题,要用unsigned long long。 |
代码
#include<cstdio> #include<iostream> #define maxn 12 #define MOD (ll)11380 #define MODx f[i][j][k][d]%=MOD; using namespace std; typedef unsigned long long ll; ll f[maxn][maxn][maxn][39]; int l1,l2,l3,D; int main(){ scanf("%d%d%d%d",&l1,&l2,&l3,&D); for(int i=0;i<=D;i++) f[0][0][0][i]=1; for(int d=1;d<=D;d++) for(int i=0;i<=l1;i++) for(int j=0;j<=l2;j++) for(int k=0;k<=l3;k++){ if(i==0&&j==0&&k==0) continue; for(int a=0;a<i;a++) for(int b=0;b<=j;b++) for(int c=0;c<=k;c++){ f[i][j][k][d]=(f[i][j][k][d]+(ll)f[i-a-1][j-b][k-c][d]*f[a][b][c][d-1])%MOD; } for(int a=0;a<j;a++) for(int b=0;b<=k;b++){ f[i][j][k][d]=(f[i][j][k][d]+(ll)f[i][j-a-1][k-b][d]*f[0][a][b][d-1])%MOD; } for(int a=0;a<k;a++){ f[i][j][k][d]=(f[i][j][k][d]+(ll)f[i][j][k-a-1][d]*f[0][0][a][d-1])%MOD; } } if(D==0){ if(l1==0&&l2==0&&l3==0) printf("1"); else printf("0"); } else if(l1==0&&l2==0&&l3==0){ printf("0"); } else cout<<(f[l1][l2][l3][D]-f[l1][l2][l3][D-1]+MOD)%MOD; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具