题目链接:【http://codeforces.com/contest/1003/problem/F】

题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空格的个数。在这个文本中找k(k>=2)个区间,使得这k个区间完全相同,字符串不能分开,然后把每段的字符串变成单个的字符,并去掉中间的空格。可能有多种方案,求文本的最小长度。【表达能力有限,望理解,具体可以看题目】

You are given a text consisting of nn space-separated words. There is exactly one space character between any pair of adjacent words. There are no spaces before the first word and no spaces after the last word. The length of text is the number of letters and spaces in it. wiwi is the ii-th word of text. All words consist only of lowercase Latin letters.

Let's denote a segment of words w[i..j]w[i..j] as a sequence of words wi,wi+1,…,wjwi,wi+1,…,wj. Two segments of words w[i1..j1]w[i1..j1] and w[i2..j2]w[i2..j2] are considered equal if j1−i1=j2−i2j1−i1=j2−i2, j1≥i1j1≥i1, j2≥i2j2≥i2, and for every t∈[0,j1−i1]t∈[0,j1−i1] wi1+t=wi2+twi1+t=wi2+t. For example, for the text "to be or not to be" the segments w[1..2]w[1..2] and w[5..6]w[5..6] are equal, they correspond to the words "to be".

An abbreviation is a replacement of some segments of words with their first uppercase letters. In order to perform an abbreviation, you have to choose at least two non-intersecting equal segments of words, and replace each chosen segment with the string consisting of first letters of the words in the segment (written in uppercase). For example, for the text "a ab a a b ab a a b c" you can replace segments of words w[2..4]w[2..4] and w[6..8]w[6..8] with an abbreviation "AAA" and obtain the text "a AAA b AAA b c", or you can replace segments of words w[2..5]w[2..5] and w[6..9]w[6..9] with an abbreviation "AAAB" and obtain the text "a AAAB AAAB c".

What is the minimum length of the text after at most one abbreviation?

题解:

  dp[i][j]表示从第i个字符出开始的串和从第j个字符串开始的串的有多少个公共前缀字符串。因为n不是很大,所以可以暴力枚举。从前到后枚举,从第i个位置开始,长度为x(x个字符串)的串,有几个重复的,若重复的个数大于等于二则统计答案。实现的时候,可以用string暴力比较,也可以用HASH的方法,把字符串HASH成一个数字,这道题HASH卡的比较严格,我用双值HASH才跑过全部数据。具体看代码。(思路是看了某个大神的代码才理解到的,共同学习)。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int M = ;
const int mod[M] = { (int)1e9 + , (int)1e9 + };
struct Hash
{
int a[M];
Hash(int x = )
{
for (int i = ; i < M; i++)
a[i] = x;
}
Hash(const vector<int> &v)
{
for (int i = ; i < M; i++)
a[i] = v[i];
}
Hash operator * (const Hash &x) const
{
Hash ret;
for (int i = ; i < M; i++)
ret.a[i] = (LL)a[i] * x.a[i] % mod[i];
return ret;
}
Hash operator - (const Hash &x) const
{
Hash ret;
for (int i = ; i < M; i++)
{
ret.a[i] = a[i] - x.a[i];
if (ret.a[i] < )
ret.a[i] += mod[i];
}
return ret;
}
Hash operator + (const Hash &x) const
{
Hash ret;
for (int i = ; i < M; i++)
{
ret.a[i] = a[i] + x.a[i];
if (ret.a[i] >= mod[i])
ret.a[i] -= mod[i];
}
return ret;
}
bool operator == (const Hash &x) const
{
for (int i = ; i < M; i++)
if (a[i] != x.a[i])
return false;
return true;
}
};
const Hash seed = Hash({ , }); const int maxn = 1e5 + ;
const int maxm = ;
Hash sum[maxm];
int n, len[maxm], dp[maxm][maxm];
char s[maxn]; Hash Hash_tab(int ln)
{
Hash ret;
for(int i = ; i < ln; i++)
{
LL tmp = (LL)(s[i] - 'a' + );
ret = ret * seed + Hash({tmp, tmp});
}
return ret;
} int main ()
{
scanf("%d", &n);
int sum_len = n - ;
for(int i = ; i < n; i++)
{
scanf("%s", s);
len[i] = strlen(s);
sum_len += len[i];
sum[i] = Hash_tab(len[i]);
}
for(int i = n - ; i >= ; i--)
for(int j = n - ; j >= && j > i; j--)
dp[i][j] = (len[i] == len[j] && sum[i] == sum[j]) ? + dp[i + ][j + ] : ;
int ans = sum_len;
for(int i = ; i < n; i++)
{
int ret = -;
for(int j = ; i + j < n; j++)
{
ret += len[i + j];
int cnt = , k = i + j + ;
while(k < n)
{
if(dp[i][k] >= j + )
{
k += j;
cnt++;
}
k++;
}
if(cnt >= )
ans = min(ans, sum_len - ret * cnt);
}
}
printf("%d\n", ans);
return ;
}

CF 494 F. Abbreviation(动态规划)的更多相关文章

  1. CF 633 F. The Chocolate Spree 树形dp

    题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...

  2. CF #271 F Ant colony 树

    题目链接:http://codeforces.com/contest/474/problem/F 一个数组,每一次询问一个区间中有多少个数字可以整除其他所有区间内的数字. 能够整除其他所有数字的数一定 ...

  3. Leetcode 494 Target Sum 动态规划 背包+滚动数据

    这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20) ...

  4. CF 1138 F. Cooperative Game

    F. Cooperative Game 链接 题意: 有10个玩家,开始所有玩家在home处,每次可以让一些玩家沿着边前进一步,要求在3(t+c)步以内,到达终点. 分析: 很有意思的一道题.我们构造 ...

  5. CF 1041 F. Ray in the tube

    F. Ray in the tube 链接 题意: 有两条平行于x轴的直线A,B,每条直线上的某些位置有传感器.你需要确定A,B轴上任意两个整点位置$x_a$,$x_b$,使得一条光线沿$x_a→x_ ...

  6. 【Cf #502 F】The Neutral Zone

    本题把$log$化简之后求得就是每个质数$f$前的系数,求系数并不难,难点在于求出所有的质数. 由于空间限制相当苛刻,$3e8$的$bitset$的内存超限,我们考虑所有的除了$2$和$3$以外的质数 ...

  7. CF 868 F. Yet Another Minimization Problem

    F. Yet Another Minimization Problem http://codeforces.com/contest/868/problem/F 题意: 给定一个长度为n的序列.你需要将 ...

  8. CF 1051 F. The Shortest Statement

    F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...

  9. CF 1042 F. Leaf Sets

    F. Leaf Sets http://codeforces.com/contest/1042/problem/F 题意: 将所有的叶子节点分配到尽量少的集合,一个可行的集合中两两叶子节点的距离< ...

随机推荐

  1. 函数和常用模块【day06】:模块特殊变量(十四)

    from test import test ''' __mame__ # 当前文件为主文件是等于__main__.用于调用时不执行一些命令 __file__ # 当前文件的路径,相对路径 __cach ...

  2. 那些年的 网络通信之 TCP/IP 传输控制协议 ip 加 端口 客户端上传文件到服务器端服务器端返回上传成功消息

    多线程开启, 客户端通过 Socket 流 上传文件到服务端的一个小程序练习. 1. 抓住阻塞式方法,去调试 2. 获取对应流对象操作对应的对象 这时候自己不能懵,一定要清晰,最好命名就能区别,一搞混 ...

  3. 读asyncio模块源码时的知识补漏

    硬着头皮看了一周的asyncio模块代码,了解了大概的执行流程,引用太多,成尤其是对象间函数的引用. 光是这么一段简单的代码: # coding: utf8 import asyncio import ...

  4. [整理]zepto的初次使用

    http://www.css88.com/doc/zeptojs_api/ http://chaoskeh.com/blog/some-experience-of-using-zepto.html

  5. 基于Window10搭建android开发环境

    一.安装JDK 1.下载(网页链接) 2.双击安装文件进行安装,安装在合适目录,例如:D:\Java\jdk1.8.0_201与D:\Java\jre1.8.0_201 3.设置环境变量 3.1.JA ...

  6. perl6 中将 字符串 转成十六进制

    say Blob.new('abcde'.encode('utf8')).unpack("H*"); say '0x'~'abcde'.encode('utf8').unpack( ...

  7. 【工具】用命令行与Python使用YARA规则

    1.前言 YARA是一款旨在帮助恶意软件研究人员识别和分类恶意软件样本的开源工具,使用YARA可以基于文本或二进制模式创建恶意软件家族描述与匹配信息.现在已经被多家公司所运用于自身的产品. 2.YAR ...

  8. 创蓝语音服务(语音通知验证码).net

    public static string PostUrl = "http://zapi.253.com/msg/HttpBatchSendSM"; static void Main ...

  9. 常用SQL函数(字符串分隔转表、自增长转编号)

    字符串分隔转表 -- ============================================= -- Author: -- Create date: -- Description: ...

  10. 小白学习安全测试(四)——扫描工具-Vega

    WEB扫描工具-Vega 纯图形化界面,Java编写的开源web扫描器.两种工作模式:扫描模式和代理模式[主流扫描功能].用于爬站.处理表单,注入测试等.支持SSL:http://vega/ca.cr ...