Description

题目描述

Recently, you have found your interest in string theory. Here is an interesting question about strings.

You are given a string S of length n consisting of the first k lowercase letters.

You are required to find two non-empty substrings (note that substrings must be consecutive) of S, such that the two substrings don't share any same letter. Here comes the question, what is the maximum product of the two substring lengths?

最近,你突然迷上了字串论。下面是一个关于字符串的有趣问题。

给定一个字符串S,长度为n且包含前k个小写字母。

你被要求从S中找出两个非空子串(注意,子串必须是连续的),并且两个子串不共享任何字母。问题来了,两个子串长度乘积的最大值是多少?

Input

输入

The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

For each test case, the first line consists of two integers n and k. (1 <= n <= 2000, 1 <= k <= 16).

The second line is a string of length n, consisting only the first k lowercase letters in the alphabet. For example, when k = 3, it consists of a, b, and c.

输入的首行是一个整数T,表示测试样例的数量。1 <= T <= 50。

对于每个测试样例,第一行有2个整数n和k。(1 <= n <= 2000, 1 <= k <= 16)。

第二行有有一个长度为n的字符串,仅由字母表前k个小写字母组成。比如,k=3,组成元素为a,b,和c。

Output

输出

For each test case, output the answer of the question.

对于每个测试样例,输出问题的答案。

Sample Input - 输入样例

Sample Output - 输出样例

4

25 5

abcdeabcdeabcdeabcdeabcde

25 5

aaaaabbbbbcccccdddddeeeee

25 5

adcbadcbedbadedcbacbcadbc

3 2

aaa

6

150

21

0

Hint

提示

One possible option for the two chosen substrings for the first sample is "abc" and "de".

The two chosen substrings for the third sample are "ded" and "cbacbca".

In the fourth sample, we can't choose such two non-empty substrings, so the answer is 0.

对于第一个例子,其中一种可行的子串选择方案为"abc"和"de"。

第三个例子选择的子串为"ded"和"cbacbca"。

第四个例子中,我们无法找出两个非空子串,所以答案为0。

【题解】

解题思路:枚举,贪心/搜索,状态压缩/转移。

代码构架:枚举,状态压缩/转移,贪心。

枚举:

  因为最多只有前16个字母,一共216种状态,可以使用二进制压缩成一个int来记录每种字母出现的状态(当然你要用unsigned short我也不栏你_(:3 」∠)_,不过int明显看着舒服敲着方便。某人:你再说就要离题了啊,喂!)

  枚举的时候可以指定开头再叠加状态,也可以按01背包来写,记录下每种状态子串长度的最大值。

贪心/搜索:

  假如我们现在选了0001状态的子串,那么秉持着不拿人民一针一线(误)的优(hen)良(tai)作风,只要最后面不是1的我都要了!

  因此得到在可选情况下最好的状态1110。

那么问题来了,学挖掘机……哦不,1110的字符串长度可能是0啊,我们要找的可能是1100,1010,***0。那么把***0中的最大长度丢到1110中,就可以得到1110(其实是***0)的最大长度。

使用位运算可以很方便地完成比较。

状态压缩/转移:

大道无言,百态汇流。

【代码 C++】

 #include<cstdio>
#include<cstring>
#include<algorithm>
int n, k, bag[ << ], bit[];
int fid(){
memset(bag, , sizeof(bag));
char data[];
gets(data);
int i, len, temp, ed;
for (i = ; i < n; i += ){//枚举
--i;
for (len = , temp = ; i + len < n; ++len){
temp |= bit[data[i + len] - 'a'];
bag[temp] = std::max(bag[temp], len);
}
}
for (i = , ed = bit[k]; i < ed; ++i){//压缩状态
for (temp = ; temp <= k; ++temp){
if (i & bit[temp]) bag[i] = std::max(bag[i], bag[i^bit[temp]]);
}
}
for (i = , len = , --ed; i < ed; ++i){//搜索
len = std::max(len, bag[i] * bag[i^ed]);
}
return len;
}
int main(){
for (int i = , j = ; i < ; ++i, j <<= ) bit[i] = j;
int T;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &k), getchar();
printf("%d\n", fid());
}
return ;
}
 #include<cstdio>
#include<cstring>
short bag[];
int n, k, letter[];
int fid(){
memset(bag, , );
char data[];
gets(data);
int i, len, temp, ed = << k;
--ed;
for (i = ; i < n; i += ){
--i;
for (len = , temp = ; i + len < n && temp^ed; ++len){
temp |= letter[data[i + len] - 'a'];
if (bag[temp] < len) bag[temp] = len;
}
}
for (i = ; i <= ed; ++i){
for (temp = ; temp <= k; ++temp)
if (i & letter[temp] && bag[i] < bag[i^letter[temp]])
bag[i] = bag[i^letter[temp]];
}
for (i = , len = ; i < ed; ++i){
temp = bag[i] * bag[i^ed];
if (len < temp) len = temp;
}
return len;
}
int main(){
for (n = , k = ; n < ; ++n, k <<= ) letter[n] = k;
int T;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &k), getchar();
printf("%d\n", fid());
}
return ;
}

FZU 2218

FZU 2218 Simple String Problem(简单字符串问题)的更多相关文章

  1. FZU - 2218 Simple String Problem(状压dp)

    Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...

  2. FZU - 2218 Simple String Problem 状压dp

    FZU - 2218Simple String Problem 题目大意:给一个长度为n含有k个不同字母的串,从中挑选出两个连续的子串,要求两个子串中含有不同的字符,问这样的两个子串长度乘积最大是多少 ...

  3. (比赛)A - Simple String Problem

    A - Simple String Problem Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%lld & ...

  4. hdu------(1757)A Simple Math Problem(简单矩阵快速幂)

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  5. FZU 2215 Simple Polynomial Problem(简单多项式问题)

    Description 题目描述 You are given an polynomial of x consisting of only addition marks, multiplication ...

  6. fzu2218 Simple String Problem

    Accept: 2    Submit: 16 Time Limit: 2000 mSec    Memory Limit : 32768 KB  Problem Description Recent ...

  7. O - String Problem KMP 字符串最小表示法

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

  8. HDU 5284 wyh2000 and a string problem(字符串,水)

    题意:比如给你一个串,要求判断wyh是不是它的子序列,那么你只需要找一个w,找一个y,再找一个h,使得w在y前面,y在h前面即可.有一天小学生拿着一个串问他“wyh是不是这个串的子序列?”.但是wyh ...

  9. FZU2218 Simple String Problem(状压DP)

    首先,定义S,表示前k个字符出现的集合,用二进制来压缩. 接下来,推出dp1[S],表示集合为S的子串的最长长度. 然后根据dp1[S]再推出dp2[S],表示集合为S或S的子集的子串的最长长度. 最 ...

随机推荐

  1. Error while trying to retrieve text for error ORA-01019 的解决办法

    这个问题涉及到 64 位的oracle服务, 和32位的客户端导致的问题. 环境如下: win8.1 + 64位oracle 11.1 做服务器, 客户端由于采用32位程序,不支持64位的oracle ...

  2. 【翻译】了解ASP.NET MVC的HTML助手

    原文:Understanding HTML Helpers in ASP.NET MVC 作 者:Shailendra Chauhan works as Software Analyst at rep ...

  3. linux curl用法详解

    linux ‍‍curl用法详解 ‍‍curl的应用方式,一是可以直接通过命令行工具,另一种是利用libcurl库做上层的开发.本篇主要总结一下命令行工具的http相关的应用, 尤其是http下载方面 ...

  4. symfony中twig的模板变量与注释

    程序会传递给模板若干变量,你需要在模板里输出他们.例如输出$hello .1{{ hello }}.如果传递给模板的是对象或者数组,你可以使用点. 来输出对象的属性或者方法,或者数组的成员.或者你可以 ...

  5. destoon 深度整合discuz x2 UC 之免邮箱二次验证

    destoon中member/my.php,信息发布入口处判断是否已在dx中做了验证,如果已经验证,则不再提示验证,否则其中dt的验证页面. 在home.php.php. group.php. for ...

  6. oracle 执行执行动态存储过程名---其实就是存储过程名是个字符串参数

    假设我有一个过程P1(V1 IN VARCHAR2),另一有一个过程EX(P IN VARCHAR2,P IN VARCHAR2),第一个参数是过程名,第二个参数是指定过程的参数,我执行EX('P1' ...

  7. Serializable接口使用纪实

    这两天依领导要求使用sonar工具测试了一下项目代码,其中有一个问题是 而这个类的结构大概是这样的: public class Demo<T> implements Serializabl ...

  8. ACM题目————马拦过河卒

    题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...

  9. tomcat部署到根路径

    在Tomcat中部署war包很简单: 首先,直接把相应的war包放到$TOMCAT_HOME/webapps下,不用建目录: 然后,修改$TOMCAT_HOME/conf/server.xml,在Ho ...

  10. syntactically incorrect() 404

    遇到这个错误就来记录一下吧. 这个错误是springMVC报出的错误.大致的意思就是form传值的类型和controller中的参数不符. 有可能是名字错误,有可能是类型不对.比如前面你传来的是  p ...