搜索题目

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);
}
}

 

你可能感兴趣的:(搜索)