1. joj 2391 words
题意:给不超过12个word,找出最长的单词序列,其中,前一个单词的最后一个字母,等于后一个单词的第一个字母。
思路:刚开始,我以为水题,直接以每一个单词为起点进行DFS,搜索中记录最大值,结果TLE。必须剪枝了,想了老长时间,就是没想出怎么处理出现回路的问题,中午坐电脑前,忽然有了个思路。就是记录以每个word作为第一个word的长度,并且在搜索中由后向前搜,这样的话,剪枝就好设置了:如果当前长度+前一个单词M的长度 小于等于 所记录的M作为第一个的长度,就没有必要再搜了;否则,更新M的记录,继续向前搜。
代码:
代码
#include<stdio.h>
#include<string.h>
struct Word{
char s, e;
int len;
};
int n;
Word dict[20];
bool visited[20];
int start_len[20];//以第i个单词开始的最大长度
void DFS(int k, int cur_len){
visited[k] = true;
for(int i=0; i<n; ++i){
if(!visited[i] && dict[k].s == dict[i].e){//从后向前走
if(start_len[i] < dict[i].len + cur_len){//剪枝
start_len[i] = dict[i].len + cur_len;
DFS(i, start_len[i]);
}
}
}
}
int main(){
// freopen("in", "r", stdin);
char buffer[120];
int len;
while(scanf("%d", &n) != EOF){
for(int i=0; i<n; ++i){
scanf("%s", buffer);
len = strlen(buffer);
dict[i].s = buffer[0];
dict[i].e = buffer[len-1];
dict[i].len = len;
start_len[i] = len;
}
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j)
visited[j] = false;
DFS(i, dict[i].len);
}
len = start_len[0];
for(int i=0; i<n; ++i)
if(len < start_len[i])
len = start_len[i];
printf("%d\n", len);
}
}