P7541 [COCI2009-2010#1] DOBRA 题解

题目传送门

错误思路

暴力搜,搜每个下划线位置的字母,记下划线个数为 $m$,则 $m\le10$,时间复杂度 $O(26^m)$,超时。

正解

思路

很容易想到其实 $5$ 个元音字母没有本质区别,除了 $\texttt{L}$ 外的辅音字母也一样。我们在搜时只需要在下划线处搜:

  1. 元音字母
  2. 除 $\texttt{L}$ 外的辅音字母
  3. $\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。 ——题面

posted @   Po7ed  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示