题意:
  给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. Oracle 错误代码

    ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...

  2. iOS进阶学习-CoreData

    一.CoreData数据库框架的优势 1.CoreData数据持久化框架是Cocoa API的一部分,首次在iOS5版本的系统中出现,它允许按照实体-属性-值模型组织数据,并以XML.二进制文件或者S ...

  3. php取整函数floor(),round(),intval(),ceil()

    ceil -- 进一法取整说明float ceil ( float value )返回不小于 value 的下一个整数,value 如果有小数部分则进一位.ceil() 返回的类型仍然是 float, ...

  4. 通过store为toolbar添加按钮

    目的是实现导航条toolbar可以动态加载按钮. ExtJS的版本是4.0. 实现方案有两个.方案一:添加render事件监听,在监听事件处理函数中使用Ext.Ajax获取按钮信息,实现动态添加按钮. ...

  5. 加速传感器(CoreMotion) swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  6. js selector libray

    http://sizzlejs.com/ http://selectivizr.com/

  7. Node.js 学习(一) 安装配置

    Windowv 上安装Node.js Windows 安装包(.msi) : 32 位安装包下载地址 : http://nodejs.org/dist/v0.10.26/node-v0.10.26-x ...

  8. android开发 两张bitmap图片合成一张图片

    场景:对android4.4解码gif(解码文章见前面一篇)后的图片进行每帧处理,android4.3 解码出来的每帧都很完整,但是到android4.4版本就不完整了,每帧都是在第一帧的基础上把被改 ...

  9. bzoj 1565 最大权闭合子图

    因为每个植物都有保护的点(每排相邻的右面的算是保护左面的),所以连他和保护 的点一条边,然后每个点有自己的权值,要找到最大的权值且满足每个点在访问时他 的前驱一定被访问,那么反向建边,转化为后继必须访 ...

  10. bzoj 2743 树状数组离线查询

    我们按照询问的右端点排序,然后对于每一个位置,记录同颜色 上一个出现的位置,每次将上上位置出现的+1,上次出现的-1,然后 用树状数组维护就好了 /************************** ...