FOJ Problem 2218 Simple String Problem

来源:互联网 发布:呼死你软件多少钱 编辑:程序博客网 时间:2024/05/16 10:13
Problem 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?

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.

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

Sample Input
4
25 5
abcdeabcdeabcdeabcdeabcde
25 5
aaaaabbbbbcccccdddddeeeee
25 5
adcbadcbedbadedcbacbcadbc
3 2
aaa Sample Output
6
150
21

0


先说一下这道题的题意,就是说给你一串字符串,n表示字符串的长度,k表示串中只包含字母表中前k个字母,并且都为小写,让你在长度为n的输入串中选择两个连续的子串,不能相交,并且在第一个子串中的字母在第二个子串中都没出现,即两个子串不含有相同字母,求成两个子串长度乘积的最大值。

这一题先是无从下手,网上说是状态压缩dp,没听懂,以前没做过这方面的题。所以沉寂了好久。但是我想不会做咱们就穷举不就得了,心想会超时,但试了一下,压着时间过了!所以穷举也是要技巧的,有技巧的穷举其实效率还是蛮高的。思路是这样的! 代码已经注释看一下喽


//其实输入的字符串最后是要分成两部分,记为0串与1串 //即输入的字符串中的字符分为两个集合,用0, 1表示 # include <cstdio>using namespace std;char s[2010];//存储输入的原串int status[20];//表示状态,s[i]=1表示字母表中第i个字母在1串中 int change[2010];//将s字符串转化成0,1串 int n, k;//n, k的表示跟题目中一样 int ans;int max1_s[2010], max0_s[2010];//max1_s[i]表示change数组中到以第i个1结尾的最大长度 //max0_s[i]表示change数组中到以第i个0结尾的最大长度int max0, max1;//记录max1_s[i],max0_s[i]最大值void func(int b){//b从0开始 if(b==k){//到达k,递归终止 max0=0;max1=0;for(int i=0; i<=n-1; i++){change[i+1]=status[s[i]-96];}max1_s[0]=0;max0_s[0];for(int i=1; i<=n; i++){if(change[i]){//change[i]==1max1_s[i]=max1_s[i-1]+1;//加上前一个长度 max0_s[i]=0;//目前为一,初始化为0 if(max1_s[i]>max1){//更新最大值 max1=max1_s[i];}}else{//change[i]==0max0_s[i]=max0_s[i-1]+1;//加上前一个长度max1_s[i]=0;//目前为一,初始化为0 if(max0_s[i]>max0){//更新最大值max0=max0_s[i];}}}if(max0*max1>ans){ans=max0*max1;}}else{//以下对status[i]的赋值是对于选与不选经行赋值的 status[b]=0;func(b+1);status[b]=1;func(b+1);}}int main(){int i, j, t;scanf("%d", &t);//测试数据的组数 for(i=1; i<=t; i++){scanf("%d%d", &n, &k);getchar();scanf("%s", s);ans=0;func(0);printf("%d\n", ans);}return 0;}


0 0
原创粉丝点击