FZU - 2218 Simple String Problem 状压dp
FZU - 2218Simple String Problem
题目大意:给一个长度为n含有k个不同字母的串,从中挑选出两个连续的子串,要求两个子串中含有不同的字符,问这样的两个子串长度乘积最大是多少?
根据题目所给的k<=16很自然的想到用状压dp来处理,但不知道该dp个什么,在观摩大佬的做法后才明白。我们用0000000000000000到1111111111111111表示pomnlkjhgfedcba的字符存不存在的状态,某个字符存在的话对应位就是1,反之就是0。一开始dp[x]就表示,在给出的串中状态x的最长长度,这样很好的处理重复的字符了,比如像aab,abaab,ab,ba这些串,他们的状态都是3(也就是a位和b位是1其他全0),然后dp[3]就是5(abaab这个)。所以我们遍历一遍S的所有子串就可以得到所有状态在子串中的最长长度。
因为是两个含有不同字符的子串长度相乘,假设目前k是4,然后一个子串是的状态是1001,那么和它含有不同字符的子串的状态分别是0010,0100,0110,也就是1001反状态0110的所有子状态,我们直接让dp[x]去和它所有反状态的子状态相乘的话就会有很多种组合,处理上就非常的麻烦,所以这时就有个优化,让dp[x]表示它和它子串中最长的长度,也就是1001,包含了0001,1000,1001这几种状态的情况,然后在判断答案时直接让dp[x]和它的反状态dp[(1<<k)-1-i](全1减去x)相乘就包含了它们各自子串的情况。具体的细节如代码。
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=(<<)+;
int dp[N];
char s[];
int main()
{
int n,k,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
scanf("%s",s);
for(int i=;i<(<<k);i++)
dp[i]=;//初始化所有状况的初始最长长度
for(int i=;i<n;i++)//遍历所有子串的状态
{
int x=;
for(int j=i;j<n;j++)
{
x|=<<(s[j]-'a');//因为每个字符不管它在这个子串中重复出现了几次
//只要出现了一次,对于位置就是1,所以直接对位与|
dp[x]=max(dp[x],j-i+);
}
}
for(int i=;i<(<<k);i++)//让每个状态包含它的子状态
for(int j=;j<k;j++)
if(i&(<<j))//对位是1的异或取反
dp[i]=max(dp[i],dp[i^(<<j)]);
//因为像10110包含了10100的状态,而10100已经包含了10000和00100
//所以只需要有1的位置对位异或,10110就能包含它所有子串的状态
int ans=;
for(int i=;i<(<<k);i++)
ans=max(ans,dp[i]*dp[(<<k)--i]);//一个串的结果和它相反串的结果相乘
printf("%d\n",ans);
}
return ;
}
状压状压hashaki
FZU - 2218 Simple String Problem 状压dp的更多相关文章
- FZU - 2218 Simple String Problem(状压dp)
Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...
- FZU 2218 Simple String Problem(简单字符串问题)
Description 题目描述 Recently, you have found your interest in string theory. Here is an interesting que ...
- CF11D A Simple Task(状压DP)
\(solution:\) 思路大家应该都懂: 状压DP:\(f[i][j]\),其中 \(i\) 这一维是需要状压的,用来记录19个节点每一个是否已经走过(走过为 \(1\) ,没走为 \(0\) ...
- CF11D-A Simple Task【状压dp】
正题 题目链接:https://www.luogu.com.cn/problem/CF11D 题目大意 给出\(n\)个点\(m\)条边的一张简单无向图,求它的简单环的个数. \(1\leq n\le ...
- FZU-2218 Simple String Problem(状态压缩DP)
原题地址: 题意: 给你一个串和两个整数n和k,n表示串的长度,k表示串只有前k个小写字母,问你两个不含相同元素的连续子串的长度的最大乘积. 思路: 状态压缩DP最多16位,第i位的状态表示第i位 ...
- cf 11D A Simple Task(状压DP)
题意: N个点构成的无向图,M条边描述这个无向图. 问这个无向图中共有多少个环. (1 ≤ n ≤ 19, 0 ≤ m) 思路: 例子: 4 6 1 2 1 3 1 4 2 3 2 4 3 4 答案: ...
- FZU 1025 状压dp 摆砖块
云峰菌曾经提到过的黄老师过去讲课时的摆砖块 那时百度了一下题目 想了想并没有想好怎么dp 就扔了 这两天想补动态规划知识 就去FZU做专题 然后又碰到了 就认真的想并且去做了 dp思想都在代码注释里 ...
- zoj3777 Problem Arrangement(状压dp,思路赞)
The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
随机推荐
- Java EE javax.servlet ServletContainerInitializer接口
ServletContainerInitializer接口 public interface ServletContainerInitializer 一.介绍 该接口,允许在 web 应用程序的启动阶 ...
- 怎样理解Node对象接口
dom中的节点都继承自Node接口, 也就是说, 所有的节点都具有Node接口所规定的属性和方法, 比如下面这个 <a> 标签, 它也继承了Node的所有属性和方法: 可以认为Node接口 ...
- 异常-Throwable的几个常见方法
package cn.itcast_04; import java.text.ParseException; import java.text.SimpleDateFormat; import jav ...
- (四)创建基于maven的javaFX+springboot项目,用户界面与后台逻辑分离方式
下面来介绍创建maven的javaFX+springboot项目,基于用户界面与后天逻辑分离的方式,用户界面使用fxml文件来常见,类似于jsp,可以引入css文件修饰界面 maven依赖 <d ...
- C++:函数先声明后实现
贼神奇的是,直到昨天在写flex规则的时候我才知道C++中的函数要么在使用之前先定义,要么将实现放在调用之前,不允许先调用后实现.之前一年多竟然不知道这件事,汗````,当然也是可能这件事本身和我思考 ...
- python中获取当前位置所在的行号和函数名(转)
http://www.vimer.cn/2010/12/%E5%9C%A8python%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E4%BD%8D%E7 ...
- 查询SQL Server版本号
一.查看SQL Server 2005版本号 SELECT @@VERSION 显示以下信息: Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) ...
- O038、Shelve Instance 操作详解
参考https://www.cnblogs.com/CloudMan6/p/5524751.html Instance 被 Suspend 后虽然处于 shutdown 状态,但 Hypervis ...
- redis集群+JedisCluster+lua脚本实现分布式锁(转)
https://blog.csdn.net/qq_20597727/article/details/85235602 在这片文章中,使用Jedis clien进行lua脚本的相关操作,同时也使用一部分 ...
- 封装一些简单的 dom 操作
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...