题意:
  给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. Android SDK API (2.2,2.3,3.0)中文版文档

    转的一篇.觉得很有用. Android SDK API (2.2,2.3,3.0)中文版文档 地址:http://android.laoguo.org固定连接:http://www.laoguo.or ...

  2. C/C++ 关于大小端模式

    大端模式:  数据的高字节存在低地址  数据的低字节存在高地址 小端模式:  数据的高字节存在高地址  数据的低字节存在低地址 如图,i为int类型占4个字节,但只有1个字节的值为1,另外3个字节值为 ...

  3. Redis 五:配置主从复制功能

    redis的主从复制事实上是非常简单的一件事情,甚至比mysql的配置还简单,因为基本不需要在主服务器上做任何操作 我们在同一台服务器上开不同的端口进行测试操作(安装部分就不说啦,前面的文章有::) ...

  4. JavaScript高级程序设计之动态脚本及动态样式

    1.动态加载脚本(src 原理,异步,支持跨域) var loadScript = function (url, callback) { var script = document.createEle ...

  5. Windows Phone中In-App Purchase应用内购买

    前言       应用内购买(In-App Purchase)对于开发者来说绝对是一个非常重要的功能,它提供了一个便捷的入口供用户来购买付费.在IAP盛行之前的游戏运营商一般都是通过接入第三方支付入口 ...

  6. Linux下Nginx的安装与配置

    安装前需要安装pcre:ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/1.解压缩:     tar xjpf pcre-7.8.tar.b ...

  7. 【EF Code First】Migrations数据库迁移

    1,打开工具->NuGet程序管理器->程序包管理器控制台 默认项目中要选择  数据访问上下文类  所在的项目 我的DB是在命名空间CodeFirst.UI下的所以选择CodeFirst. ...

  8. bootsrap check 获取选中

    代码如下: <label> <input type="checkbox" name="PartEdge2" value="false ...

  9. java数据结构和算法------合并排序

      package iYou.neugle.sort; public class Merge_sort { public static void MergeSort(double[] array, i ...

  10. iOS 进阶 第十七天(0420)

    0420 凡是继承了UIResponder的类都可以做响应者 响应事件的传递是由底到高来传递,响应者链条是由高到底来响应 相应事件的传递(由底到高 找到正在和用户触摸交互的view) 准则:事件由父控 ...