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 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
随机推荐
- LeetCode面试常见100题( TOP 100 Liked Questions)
LeetCode面试常见100题( TOP 100 Liked Questions) 置顶 2018年07月16日 11:25:22 lanyu_01 阅读数 9704更多 分类专栏: 面试编程题真题 ...
- ueditor 编译出错
错误 CS0433 类型“Uploader”同时存在于“com.80community.xy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nul ...
- 【ExtJs】ext前台中的日期控件传输时间到后台的转换保存过程
//前台日期选择框 {fieldLabel:, padding: ',afterLabelTextTpl: required,allowBlank: false,format: 'Y-m-d H:i: ...
- vim之快捷键
Vim 编辑器是一个基于命令行的工具,是传奇编辑器 vi 的增强版.尽管图形界面的富文本编辑有很多,但是熟悉 Vim 对于每一位 Linux 的使用者都能有所帮助——无论你是经验丰富的系统管理员,还是 ...
- vue-loading图
父组件给子组件src地址: columns(){ return [ {'title': '图片', 'key': 'img', render(h, {row}){ return h(LoadingIm ...
- haproxy + keepalived + mycat 高可用与负载均衡集群配置 centos7
架构如上,但是其实keepalived.haproxy.Mycat都可以多台(比如keepalived.haproxy.Mycat各3台,3台keepalived抢占vip,然后抢到vip的hapro ...
- Centos6.8 rabbitmq搭建且修改默认端口
一.安装依赖环境 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ ...
- 一个简单的创建xml方式
, matnr LIKE mara-matnr , maktx LIKE makt-maktx , END OF itab_matnr . , class LIKE m_wwgha-class,&qu ...
- Java高并发程序设计学习笔记(十):并发调试和JDK8新特性
转自:https://blog.csdn.net/dataiyangu/article/details/87631574 多线程调试的方法使用Eclipse进行多线程调试线程dump及分析分析死锁案例 ...
- mybatis sql语句中 in() 长度为0或null的情况
mybatis sql语句中 in() 长度为0或null的情况 比如: select * from A where colName IN <foreach collection="m ...