P7541 [COCI2009-2010#1] DOBRA 题解
错误思路
暴力搜,搜每个下划线位置的字母,记下划线个数为 $m$,则 $m\le10$,时间复杂度 $O(26^m)$,超时。
正解
思路
很容易想到其实 $5$ 个元音字母没有本质区别,除了 $\texttt{L}$ 外的辅音字母也一样。我们在搜时只需要在下划线处搜:
- 元音字母
- 除 $\texttt{L}$ 外的辅音字母
- $\texttt{L}$
三个情况即可。
需要注意的是: 由于搜元音时,我们可以在下划线处填任意元音字母,所以填元音字母的方案数要乘以 $5$。同理,搜除 $\texttt{L}$ 外的辅音字母时要乘以 $26-5-1=20$。$\texttt{L}$ 就不需要了,因为只可能填 $\texttt{L}$。
代码
#include <iostream> using namespace std; string s; #define isyy(c) (c=='A'||c=='E'||c=='I'||c=='O'||c=='U')//判断是否是元音 long long dfs(int dep,int y,int f,bool L)//y:连续元音个数,f:连续辅音个数,L:当前是否有‘L’ { if(y>=3||f>=3) { return 0; } if(s.size()<=dep) { return (long long)L;//有‘L’才“令人愉快” } long long t=0; if(s[dep]=='_') { //填元音字母 s[dep]='A';//用‘A’代表元音 t+=5*dfs(dep+1,y+1/* 连续元音数量加1 */,0/* 连续辅音数量清0。下同。 */,L);//一共可填5种元音 //填辅音字母 s[dep]='B';//用‘B’代表辅音 t+=20*dfs(dep+1,0,f+1,L);//‘L’特殊考虑,26-5-1=20,一共可填20种辅音 //填‘L’ s[dep]='L'; t+=dfs(dep+1,0,f+1,true); s[dep]='_';//恢复原状 return t; } else//如果不是下划线 { if(isyy(s[dep])) { return dfs(dep+1,y+1,0,L); } else { if(s[dep]=='L') { return dfs(dep+1,0,f+1,true); } else { return dfs(dep+1,0,f+1,L); } } } } int main() { cin>>s; printf("%lld",dfs(0,0,0,false)); return 0; }
注意
你需要使用 $64$ 位有符号整数。在 C/C++ 中使用
long long
,Pascal 中使用int64
。 ——题面
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具