51nod 1391 01串(hash+DP)
题目链接
题意:给定一个01串S,求出它的一个尽可能长的子串S[i..j],满足存在一个位置i<=x <=j, S[i..x]中0比1多,而S[x + 1..j]中1比0多。求满足条件的最长子串长度。
初步分析:假设子串S[i..j]是满足条件的一个最长子串,且i和j均不是边界(0<i && j<n-1),则S[i-1]一定是1,否则S[i-1, j]也满足条件且比S[i, j]长,矛盾。同理可推出S[j+1]是0。用类似的逻辑进一步可推出存在一个位置i<=x <=j, S[i..x]中0比1恰好多1个,而S[x + 1..j]中1比0恰好多1个。把原数组中所有的0用-1代替,子串01个数的比较就可以转换为子串和的正负。
思路:先处理i和j不是边界的情况,根据上面的初步分析,可以枚举x,然后分别考虑到x结尾的和为-1的最长子串的长度,以x+1开头的和为1的最长子串的长度。这两个子问题都可以通过hash来解决(类似于求最长01子串,使得0和1个数相等)。i,j是边界的情况特殊处理就好。
代码虽然写得挫,还是忍不住贴一个:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + ;
char s[N];
int a[N];
int pre[N], suf[N];
int start[N], end[N];
int f[*N];
int main()
{
freopen("in.txt", "r", stdin);
while(==scanf("%s", s+)){
int n = strlen(s+);
for(int i=; i<=n; i++){
a[i] = s[i]=='' ? : -;
}
memset(f, 0x3f, sizeof(f));
memset(end, , sizeof(end));
pre[] = ;
for(int i=; i<=n; i++){
pre[i] = pre[i-] + a[i];
int tmp = pre[i] + N;
end[i] = max(, i - f[tmp+]);
f[tmp] = min(f[tmp], i);
}
memset(f, , sizeof(f));
memset(start, , sizeof(start));
suf[n+] = ;
for(int i=n; i>=; i--){
suf[i] = suf[i+] + a[i];
int tmp = suf[i] + N;
start[i] = max(, f[tmp-] - i);
f[tmp] = max(f[tmp], i);
}
int ans = ;
for(int i=; i<=n; i++){
if(pre[i]< && suf[i+]>) ans = n;
}
for(int i=; i<=n; i++){
if(pre[i]< && start[i+]>){
ans = max(ans, i+start[i+]);
}
}
for(int i=n; i>=; i--){
if(suf[i]> && end[i-]>){
ans = max(ans, n+-i + end[i-]);
}
}
for(int i=; i<=n; i++){
if(end[i]> && start[i+]>){
ans = max(ans, end[i]+start[i+]);
}
}
printf("%d\n", ans);
}
return ;
}
51nod 1391 01串(hash+DP)的更多相关文章
- 51nod——1391 01串(字符串、前缀和)
好像这题是4级题下放2级? 预处理:求每个位置 x 左区间 [ 0 , x ] 中 1 比 0 多的数量和右区间 ( x , n - 1 ] 中 0 比 1 多的数量(少就是负的).相当于求两个前缀和 ...
- 01串(dp)
01串 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 ACM的zyc在研究01串,他知道某一01串的长度,但他想知道不含有“11”子串的这种长度的01串共有多少个, ...
- COGS 862. 二进制数01串【dp+经典二分+字符串】
862. 二进制数01串 ★ 输入文件:kimbits.in 输出文件:kimbits.out 简单对比 时间限制:1 s 内存限制:128 MB USACO/kimbits(译 by ...
- NYOJ 252 01串 普通dp
题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=252 分析: dp[2][0]=2;//表示长度为2的满足要求的且以0结尾的串个数 ...
- 51nod 1391:01串
1391 01串 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 给定一个01串S,求出它的一个尽可能长的子串S[i. ...
- AC日记——还是01串 51nod 1396
还是01串 思路: 前缀和: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #in ...
- 51nod 1396 还是01串
给定一个0-1串s,长度为n,下标从0开始,求一个位置k,满足0<=k<=n, 并且子串s[0..k - 1]中的0的个数与子串s[k..n - 1]中1的个数相等. 注意: (1) 如果 ...
- JZOJ P1847:找01串
传送门 DP预处理+贪心 首先设$f[i][j]$表示长度为$i$的01串中有不大于$j$个1,然后显然 $f[i][j]=\sum_{k=1} ^{j} C[i][k]$ $C[i][j]=C[i- ...
- 完美串(区间dp)
完美串 Description 爱美之心人皆有之,GG也不例外.所以GG他对于完美串有一种热衷的爱.在GG眼中完美串是一个具有无比魅力的01子串.这个子串有之其魅力之处,对它取反后水平翻转,它又和它原 ...
随机推荐
- Eclipse & Visual Studio
VS中的解决方案 vs Eclipse中的workspace Maven包管理 vs Nuget类库管理 build path vs
- CodeForces 558C Amr and Chemistry (位运算,数论,规律,枚举)
Codeforces 558C 题意:给n个数字,对每一个数字能够进行两种操作:num*2与num/2(向下取整),求:让n个数相等最少须要操作多少次. 分析: 计算每一个数的二进制公共前缀. 枚举法 ...
- IDEA破解后无法启动
在网上找了破解IDEA的方法 原文:https://blog.csdn.net/qq_38637558/article/details/78914772 ①到这个地方下载 IntelliJ IDEA ...
- zoj3696(泊松分布)
p(k)=(y^k) / (k!) * e^(-y) 其中的y就是平均值 k就是我们要求的大小. Alien's Organ Time Limit: 2 Seconds Memory Lim ...
- Tomcat上进行项目部署与WAR包含义
一.WAR包 1.与JAR包类似,是将java类(编译好的.class)和Web资源,压缩后生成压缩包. 2. 与JAR相比,多了WEB-INF文件夹,其它多出来的内容基本都是Web资源 WEB-IN ...
- Python全栈day28(描述符应用)
描述符的使用 python是弱类型语言,及参数的赋值没有类型限制,下面通过描述符机制来实现类型限制功能 描述符应用1.py class Typed: def __get__(self, instanc ...
- CH5301 石子合并【区间dp】
5301 石子合并 0x50「动态规划」例题 描述 设有N堆沙子排成一排,其编号为1,2,3,…,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆, ...
- JavaWeb基于session和cookie的数据共享
在了解session和cookie技术之前,我们需要先了解一下什么是会话?会话可以简单理解为用户打开一个浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程称为一个会话.这样, ...
- Intellij idea中maven加载jar包很慢的解决方案.
默认加载的都是国外的源,我们可以配置国内的源. 右键项目-->maven-->Open ''setting.xml'' 复制下面的代码进去.保存. 我这里使用的版本是 ideaIU-14. ...
- Linux/Mac里复制终端Session(像SecureCRT一样)
在你的登录账户下的.ssh文件夹新建一个文件:config cd ~/.ssh config的文件中,内容为: host * ControlMaster auto ControlPath ~/.ssh ...