hust 1075 Every String Left Behind

题目描述

Elenore has a list of strings that she wants to put in a file. She could just
put them all into a file in order, but she wants to minimize the size of the
file. So she figures she can combine all the strings into one large string which
contains the original strings as substrings. Then for each string she just needs
to store the index and length of the string. For example, let‘s say the strings
she needs to store are: ? doghouse ? houseboat ? corndog Then Elenore can make
the string "corndoghouseboat" that contains all the input strings.

输入

There will be several test cases. Each test case will start with a line with
a positive integer, N, that is at most 20. Then N lines will follow each
containing a string. The strings will consist of only lowercase letters.

输出

For each test case, output a line that says "Elenore can use a string of
length L." where L is the length of the shortest string that contains all of the
input strings.

样例输入

3
doghouse
houseboat
corndog
1
hello
4
department
of
redundancy
department

样例输出

Elenore can use a string of length 16.
Elenore can use a string of length 5.
Elenore can use a string of length 22.

这是一个状态压缩dp题,可是我超时了,o(2^nn^2)的时间复杂度,过路的朋友帮忙看看怎么优化


#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;

int state[1<<20+1];
char str[21][100],stri[100],strj[100];
int len[21],a[21][21];

void init(int n)
{
for(int i=0;i<=1<<n;i++)
state[i]=99999999;
for (int i=0;i<n;i++)
state[1<<i]=len[i];
state[0]=0;
}

void strccmmpp(int n)
{
int temp;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (i==j) a[i][j]=0;
else if(i!=j)
{
temp=len[j];
for (int l=0;l<len[j];l++)
{
strj[l]=str[j][l];
strj[l+1]=NULL;
int l1=0;
bool cut=true;
for (int k=len[i]-l-1;k<len[i];k++)
if (strj[l1++]!=str[i][k]) {cut=false;break;}
if (cut) {temp-=l+1;break;}
if (l1>=len[j]) break;
}
a[i][j]=temp;
}
}
}

int main()
{
int n;
while (scanf("%d",&n)!=EOF)
{
gets(stri);
for (int i=0;i<n;i++)
{
gets(str[i]);
len[i]=strlen(str[i]);
}
init(n);
strccmmpp(n);
for (int s=0;s<(1<<n);s++)
{
for (int i=0;i<n;i++)
if (s & (1<<i))
{
for (int j=0;j<n;j++)
if ((s & (1<<j))==0)
{
state[s|(1<<j)]=min(state[s]+a[i][j],state[s|(1<<j)]);
}
}
}
printf("Elenore can use a string of length %d.\n",state[(1<<n)-1]);
}
return 0;
}

hust 1075 Every String Left Behind,布布扣,bubuko.com

时间: 2024-10-19 17:40:54

hust 1075 Every String Left Behind的相关文章

ACM选修hust 1075 组合+数学+期望值

Description Input Output Sample Input 2 2 1 0 1 1 0 3 1 0 1 1 1 0 1 1 1 0 Sample Output 0.500 1.125 题意:给出N个node,当节点为女性,且认识K个男性时,该节点就满足条件,求出所有情况满足条件的节点的期望值.想法:由于输入矩阵i X j来表示i是否认识j.故可以记录每个i认识的个数.枚举每个i,再进行排列组合计算,满足条件的个数计入count,计算期望值时除以所有情况(2^n). (最开始愚蠢的

php使用redis

在 http://www.redis.net.cn/ 能找到所有关于redis的信息,包括安装.命令.在编程语言中的使用等等.这里就不讲如何安装redis了,因为在上面的网站中都能找到.下面直接讲redis是如何在php中使用的. 一.phpredis扩展 安装phpredis扩展前需要下载phpredis扩展,下载前根据你本地php环境选择对应的phpreids扩展(选不对的话,就有可能无法使用redis了),建议使用php5.4.x版本环境. 1.php执行phpinfo()函数,根据下面截

判断是否是手机

Mobile.class.php 1 <?php 2 /** 3 * Mobile Detect Library 4 * ===================== 5 * 6 * Motto: "Every business should have a mobile detection script to detect mobile readers" 7 * 8 * Mobile_Detect is a lightweight PHP class for detecting m

编译器构造中自底向上的LALR(1)语法分析的语法分析表生成的实现

提示:阅读本文需掌握编译原理的相关基础知识 本文中使用C++语言系统地实现了龙书中LALR(1)语法分析表的构造算法,首先计算增广文法的LR(0)项集族,每一个项集只包含内核项,计算过程中自动生成了LR(0)自动机,该自动机使用基于十字链表存储结构的有向图表示.然后通过确定自发生成和传播的向前看符号算法计算各LR(0)内核项集自发生成的向前看符号(增广文法新增产生式的向前看符号不包括在内)并确定LR(0)内核项集之间向前看符号的传播关系.最后一遍扫描前将为增广文法新增产生式添加向前看符号即输入结

HUST 1328 String

11: KMP next 的强大 题意求前缀在S中出现的次数之和 next[j] 表示 S[0....NEXT[J]]==S[J-NEXT[J].....J]; 于是我们得到..后加入一个字符所得到新的前缀会多ADD[next[J]]个 #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> using namespa

hdu 1075 map的使用 字符串截取的常用手段 以及string getline 使用起来的注意事项

首先说字符串的截取套路吧 用坐标一个一个的输入 用遍历的方式逐个去检查字符串中的字符是否为符合的情况 如果是的话 把该字符放入截取string 中 让后坐标前移 如果不是的话 截取结束 坐标初始化 然后是map的使用 头文件为 <map> 定义的话 map<类型,类型> 变量名 对于map中值的传入的话 直接用数组的形式就好 这里由于有搜索 所以还要用到find函数   如果找不到的话 find返回值为end() 再就是string 类型变量的使用要注意 string类型的变量在下

HDU 1075 What Are You Talking About (Trie树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1075 map可以过...我上的字典树,小bug有点尴尬,题目没有明确给出数据范围也是无奈. 贡献了几次RE 一次WA.尴尬.discuss里面有个说注意前缀的到是给了点tip.总体来说不错 代码: 1 #define _CRT_SECURE_NO_WARNINGS 2 #include <functional> 3 #include <algorithm> 4 #include <

HUST 1698 - 电影院 组合数学 + 分类思想

http://acm.hust.edu.cn/problem/show/1698 题目就是要把一个数n分成4段,其中中间两段一定要是奇数. 问有多少种情况. 分类, 奇数 + 奇数 + 奇数 + 奇数 奇数 + 奇数 + 奇数 + 偶数 偶数 + 奇数 + 奇数 + 奇数 偶数 + 奇数 + 奇数 + 偶数 然后奇数表达成 2 * a - 1这个样子,就能列出方程. 然后就是类似于解a1 + a2 + a3 + a4 = x的问题了. #include <cstdio> #include &l

HUST 1017 - Exact cover (Dancing Links 模板题)

1017 - Exact cover 时间限制:15秒 内存限制:128兆 自定评测 5584 次提交 2975 次通过 题目描述 There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find o