[CodeForces-178F]Representative Sampling
题目大意:
给你n个字符串,要求从中选出k个字符串,使得字符串两两lcp之和最大。
思路:
动态规划。
首先将所有的字符串排序,求出相邻两个字符串的lcp长度(很显然,对于某一个字符串,和它lcp最长的字符串一定是和它字典序最接近的一个)。
接下来考虑一种类似于分治的做法。
首先找出当前区间内最小的lcp。
很显然,在这个lcp左边的字符串和右边的字符串配对时的lcp一定是这个lcp。
假如我们在左边取了i个,右边取了j个,这个lcp对答案的贡献是lcp*i*j。
接下来递归处理左半边的区间和右半边的区间即可。
考虑如何表示状态。
不难想到用f[l][r][k]表示在l~r之间取k个字符串。
每次递归枚举左右区间取的个数。
总共有n^2k种状态,如果使用记忆化,很显然数组开不下。
不使用记忆化则会TLE。
接下来考虑改进这个状态。
我们递归的时候不需要针对某一个具体的k,而是在l,r这个状态内枚举k。
显然,对于同一个l,r,k,只会被转移一次。
而同一组l,r只会被转移一次。
因此我们只需要在递归的时候存一下l,r,然后就把它废弃掉。
这就相当于动态开数组。
这样就同时解决了时间和空间上的问题。
#include<string>
#include<iostream>
#include<algorithm>
const int inf=0x7fffffff;
const int N=,K=;
std::string s[N];
int n,k,lcp[N];
int f[N<<][K],cnt;
void dp(const int &l,const int &r,const int &id) {
if(l==r) return;
int mid=;
for(register int i=l+;i<=r;i++) {
if(lcp[i]<lcp[mid]) mid=i;
}
const int lid=cnt++,rid=cnt++;
dp(l,mid-,lid);
dp(mid,r,rid);
__builtin_memset(f[id],,sizeof f[id]);
for(register int i=;i<=k;i++) {
if(i>mid-l) break;
for(register int j=;j<=k;j++) {
if(j>r-mid+) break;
if(i+j<=k) f[id][i+j]=std::max(f[id][i+j],f[lid][i]+f[rid][j]+lcp[mid]*i*j);
}
}
cnt-=;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::cin>>n>>k;
for(register int i=;i<n;i++) {
std::cin>>s[i];
}
std::sort(&s[],&s[n]);
lcp[]=inf;
for(register int i=;i<n;i++) {
lcp[i]=std::min(s[i].length(),s[i-].length());
for(register int j=;j<lcp[i];j++) {
if(s[i][j]!=s[i-][j]) {
lcp[i]=j;
}
}
}
dp(,n-,cnt++);
std::cout<<f[][k]<<std::endl;
return ;
}
[CodeForces-178F]Representative Sampling的更多相关文章
- [Codeforces178F2]Representative Sampling
Problem 给定n个字符串Si,任意选出k个字符串Ai,使得其中任意两个字符串lcp之和最大. Solution 建一棵trie树,枚举每一个节点对答案的贡献,树形dp,时间复杂度像是O(N^3) ...
- Simple Random Sampling|representative sample|probability sampling|simple random sampling with replacement| simple random sampling without replacement|Random-Number Tables
1.2 Simple Random Sampling Census, :全部信息 Sampling: 抽样方式: representative sample:有偏向,研究者选择自己觉得有代表性的sam ...
- Survey sampling
Survey sampling \(\bullet\)What is survey sampling?(c.f.census survey)(c.f.:参考,查看,来源于拉丁语) \(\bullet\ ...
- 图像抠图算法学习 - Shared Sampling for Real-Time Alpha Matting
一.序言 陆陆续续的如果累计起来,我估计至少有二十来位左右的朋友加我QQ,向我咨询有关抠图方面的算法,可惜的是,我对这方面之前一直是没有研究过的.除了利用和Photoshop中的魔棒一样的技术或者 ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
随机推荐
- jquery.cookie.js——jquery的cookie插件
一.JS文件 /*! * jQuery Cookie Plugin v1.4.1 * https://github.com/carhartl/jquery-cookie * * Copyright 2 ...
- vista风格的cms企业html后台管理系统模板——后台
链接:http://pan.baidu.com/s/1c1Cv99e 密码:20yz
- 用CRF做命名实体识别(一)
用CRF做命名实体识别(二) 用CRF做命名实体识别(三) 用BILSTM-CRF做命名实体识别 博客园的markdown格式可能不太方便看,也欢迎大家去我的简书里看 摘要 本文主要讲述了关于人民日报 ...
- python基础===python自带idle的快捷键
Ctrl + [ Ctrl + ] 缩进代码Alt+3 Alt+4 注释.取消注释代码行Alt+5 Alt+6 切换缩进方式 空格<=>TabAlt+/ 单词完成,只要文中出现过,就可 ...
- 【转载】WebDriver(C#)之十点使用心得
使用Selenium WebDriver驱动浏览器测试的过程中多多少少会遇到一些折腾人的问题,总结了一部分,做下分享. 一.隐藏元素处理(element not visible) 使用WebDrive ...
- Lempel-Ziv algorithm realization
Lempel-Ziv 复杂度程序 随着人们对非线性方法的分析越加深入,他们发现,虽然关联维度和最大李雅谱诺夫指数在分析脑电时具有一定的帮助,但是它们对数据的依赖性太强,对干扰和噪 声太敏感,而且要得到 ...
- Java Eclipse 配置
1.清除多余记录 最近用eclipse打包jar的时候,需要指定一个main函数.需要先运行一下main函数,eclipse的Runnable JAR File Specification 下的Lau ...
- CRM 业务
1. 创建CRM项目 引入插件 创建数据库 from django.db import models from django.db import models class Department(mod ...
- 推荐一个数据相关的网站tushare
推荐一个网站:tushare 使用方法如下: pip install tushare 我是使用pycharm直接安装的 抓取了浦发和光大的股票数据,并通过csv进行保存,和通过plt进行图片打印 im ...
- 洛谷P2692 覆盖 题解
题目传送门 这道题一开始想使用二维的bool型数组来存,最后统计.但看到数据范围... 所以就改用两个bool型数组(一维),分别储存横.列,最后将横.列面积求出来,再减去重复算的面积(横的个数*列的 ...