题意:
  给N个字符串,要求出一个序列,在该序列中,后一个串,是由前一个串加一个字母后得来的(顺序可以改动)。
  问最多能组成多长的序列。
思路:将给的字符串排序,再对所有的字符串按长度从小到大排序,若长度相同,则按字典序排。
     然后找出符合条件的字符串A和B(即B可由A加一个字母得来),建立边的关系。
        之后对所有根节点进行dfs深搜,如果当前的长度大于目前的maxlen,则更新,同时记录前驱节点。
   最后根据前驱节点,输出路径即可。

#include <stdio.h>
#include <map>
#include <string.h>
#include <algorithm>
#include <string>
#include <queue>
#include <vector>
#include <iostream> using namespace std;
const int maxn=;
int n=;
vector<int>son[maxn];
int fa[maxn]; //如果该节点有父节点,则fa[i]=1;否则为0,表示根节点
int tmp[maxn]; //dfs时的前驱
int pre[maxn]; //最大长度序列的前驱,也可以设置后驱,这样会方便点。
int ans[]; //输出的结果
int maxlen=; //序列的最大长度
int rear; //最长序列的尾节点 struct Word{
char str1[],str2[]; //str1为字符串,str2为对字符串中的字符排好序后的字符串
int len;
bool operator<(const Word tmp)const{
if(len==tmp.len){
if(strcmp(str2,tmp.str2)<=)
return true;
else
return false;
}
else
return len<tmp.len;
}
}word[maxn];
//判断字符串i和字符串j是否满足条件
bool isOk(int i,int j){
int l1=word[i].len;
int l2=word[j].len;
int idx=;
while(idx<l1&&word[i].str2[idx]==word[j].str2[idx])
idx++;
while(++idx<l2)
if(word[i].str2[idx-]!=word[j].str2[idx])
return false;
return true;
}
//深搜,确定以u为根节点到叶子节点的长度
void dfs(int u,int l){
if(son[u].empty()){
if(l>maxlen){
maxlen=l;
int k=u;
rear=u;
while(tmp[k]!=-){
pre[k]=tmp[k];
k=tmp[k];
}
pre[k]=-;
return;
}
}
int v;
for(int i=;i<son[u].size();i++){
v=son[u][i];
tmp[v]=u;
dfs(v,l+);
}
}
int main()
{
char s[];
while(scanf("%s",s)!=EOF){
strcpy(word[++n].str1,s);
strcpy(word[n].str2,s);
word[n].len=strlen(s);
sort(word[n].str2,word[n].str2+word[n].len);
}
sort(word+,word+n+);
memset(fa,,sizeof(fa));
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(word[i].len+==word[j].len){
if(isOk(i,j)){
son[i].push_back(j);
fa[j]=;
} }
//剪枝一下,从1766ms降到1266ms
else if(word[i].len+<word[j].len)
break;
}
}
memset(pre,-,sizeof(pre));
for(int i=;i<=n;i++){
//加上一个剪枝条件,不过速度没怎么变化。。。
if(!fa[i] && n-i+>maxlen){
memset(tmp,-,sizeof(tmp));
dfs(i,);
}
}
int p=rear;
int idx=;
ans[idx++]=p;
p=pre[p];
while(p!=-){
ans[idx++]=p;
p=pre[p];
}
for(int i=idx-;i>=;i--){
printf("%s\n",word[ans[i]].str1);
}
return ;
}

POJ 2004 Mix and Build (预处理+dfs)的更多相关文章

  1. Mix and Build(简单DP)

    Mix and Build Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3936 Accepted: 1203 Case Ti ...

  2. poj 1724 ROADS 很水的dfs

    题意:给你N个城市和M条路和K块钱,每条路有话费,问你从1走到N的在K块钱内所能走的最短距离是多少 链接:http://poj.org/problem?id=1724 直接dfs搜一遍就是 代码: # ...

  3. POJ 2831 Can We Build This One:次小生成树【N^2预处理】

    题目链接:http://poj.org/problem?id=2831 题意: 给你一个图,每条边有边权. 然后有q组询问(i,x),问你如果将第i条边的边权改为x,这条边是否有可能在新的最小生成树中 ...

  4. poj 2965 The Pilots Brothers' refrigerator (dfs)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17450 ...

  5. POJ 3321 树状数组(+dfs+重新建树)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27092   Accepted: 8033 Descr ...

  6. POJ 3009 Curling 2.0 回溯,dfs 难度:0

    http://poj.org/problem?id=3009 如果目前起点紧挨着终点,可以直接向终点滚(终点不算障碍) #include <cstdio> #include <cst ...

  7. POJ 1426 Find The Multiple --- BFS || DFS

    POJ 1426 Find The Multiple 题意:给定一个整数n,求n的一个倍数,要求这个倍数只含0和1 参考博客:点我 解法一:普通的BFS(用G++能过但C++会超时) 从小到大搜索直至 ...

  8. poj 1564 Sum It Up (DFS+ 去重+排序)

    http://poj.org/problem?id=1564 该题运用DFS但是要注意去重,不能输出重复的答案 两种去重方式代码中有标出 第一种if(a[i]!=a[i-1])意思是如果这个数a[i] ...

  9. poj 1979 Red and Black(dfs水题)

    Description There is a rectangular room, covered with square tiles. Each tile is colored either red ...

随机推荐

  1. Effective C# 学习笔记(原则二:为你的常量选择readonly而不是const)

    原则二.为你的常量选择readonly而不是const      Prefer readonly to const 对于常量,C#里面有两个不同的版本:运行时常量(readonly)和编译时常量(co ...

  2. hdu 1622 Trees on the level

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1622 小白书上的题... #include<algorithm> #include< ...

  3. orcherd 汉化

    点击这里下载汉化包,此汉化包是在是在前人的基础上精心整理修改的,后续汉化版本随时升级更新. Orchard汉化包 下载后解压缩后打开后看到如下文件夹(App_Data.Core.Modules.The ...

  4. wifi链接配置

    linux 命令行配置wlan无线网卡 无线网卡配置此页由Linux Wiki日(星期四) 09:28的工作基础上.本文介绍在Linux命令行界面中手动配置无线网卡的方法.目前流行的多数发行版都支持用 ...

  5. Web开发者和设计师必须要知道的 iOS 8 十个变化

    原文出处: mobilexweb   译文出处:罗磊(@罗罗磊磊)   欢迎分享原创到伯乐头条 喜大普奔,喜极而泣,喜当爹,随着iPhone 6和iPhone 6 plus的上市,ios 8终于在上周 ...

  6. Entity Framework 泛型使用

    因为增删改查是我们常用到的方法,我们不可能每个数据模型都去完成增删改查,这样的办法太笨拙了.我们可以写个父类(包含增删改查),然后让所有的数据模型类继承该父类.那就要求我们的父类必须使用泛型来实现. ...

  7. firebreath 在谷歌和火狐浏览器下的调试 以及打包

    在寻找插件开发资料的过程中找到了一个开发浏览器插件的开源项目——firebreath firebreath的安装以及测试我就不再叙述了,可以参考大神的文章 . http://www.blogjava. ...

  8. iOS 进阶 第十八天(0423)

    0423 - GCD( Grand Central Dispatch) block复习 请问,图中输出结果是多少?为什么? 答:结果是10.因为在定义block的时候,block会把它前面的要用到的变 ...

  9. 通过修改注册表来破解sqlyog

    Sqlyog作为一款可视化的数据库管理工具,各种方便我就不说了,但是未经汉化或者绿色过的软件存在30天的生命期,到期后我们就不可以使用了,要摸卸载重装,我们还可以去修改注册表,来延长它的生命期,具体步 ...

  10. ionic+cordova+angularJs

    ionic+cordova+angularJs 这里详细介绍下如何用ionic+cordova+angularjs搭建自己的移动端app,包括环境搭建,框架使用等,具体项目已放置在github上,可下 ...