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

 

posted on 2010-07-28 12:32  yongmou-  阅读(948)  评论(0编辑  收藏  举报