洛谷 P1278 单词游戏
题目描述
Io和Ao在玩一个单词游戏。
他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致。
游戏可以从任何一个单词开始。
任何单词禁止说两遍,游戏中只能使用给定词典中含有的单词。
游戏的复杂度定义为游戏中所使用的单词长度总和。
编写程序,求出使用一本给定的词典来玩这个游戏所能达到的游戏最大可能复杂度。
输入输出格式
输入格式:
输入文件的第一行,表示一个自然数N(1≤N≤16),N表示一本字典中包含的单词数量以下的每一行包含字典中的一个单词,每一个单词是由字母A、E、I、O和U组成的一个字符串,每个单词的长度将小于等于100,所有的单词是不一样的。
输出格式:
输出文件仅有一行,表示该游戏的最大可能复杂度。
输入输出样例
输入样例#1:
5
IOO
IUUO
AI
OIOOI
AOOI
输出样例#1:
16
思路:裸地搜索会TLE,所以尝试性的加上卡时,AC。
以下是两种卡时的方法:
按时间卡时:
#include<ctime> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,tim,ans; int vis[17]; char s[17][110]; void dfs(int num,int pre){ if(clock()-tim>10000) { cout<<ans; exit(0); } if(num>ans) ans=num; for(int i=1;i<=n;i++){ if(s[i][0]==s[pre][strlen(s[pre])-1]) if(!vis[i]){ vis[i]=1; dfs(num+strlen(s[i]),i); vis[i]=0; } } } int main(){ tim=clock(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",s[i]); for(int i=1;i<=n;i++){ vis[i]=1; dfs(strlen(s[i]),i); vis[i]=0; } cout<<ans; }
按递归层数计算时间卡时:
#include<ctime> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,tim,ans; int vis[17]; char s[17][110]; void dfs(int num,int pre){ tim++; if(tim>1000000){ cout<<ans; exit(0); } if(num>ans) ans=num; for(int i=1;i<=n;i++){ if(s[i][0]==s[pre][strlen(s[pre])-1]) if(!vis[i]){ vis[i]=1; dfs(num+strlen(s[i]),i); vis[i]=0; } } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",s[i]); for(int i=1;i<=n;i++){ vis[i]=1; dfs(strlen(s[i]),i); vis[i]=0; } cout<<ans; }
正解思路:DP,本题可以用DP解决。
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。