hihoCoder 1300 展胜地的鲤鱼旗 (括号匹配问题 dp)

#1300 : 展胜地的鲤鱼旗

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

岩手县北上市的「北上市立公园展胜地」,是陆奥国三大樱花名所之一。每年的四月中旬到五月初,这里都会举办盛大的祭奠。除了可以在盛开的樱花步道上乘坐观光马车徐行、还有横跨北上川上的鲤鱼旗,河畔还有当地特有的为祭奠祖先而编创的北上鬼剑舞。

假设,我们用一个包含 ‘(‘, ‘)‘的括号字符串来区别每面鲤鱼旗的方向。一段括号序列被称为合法的,当且仅当满足两个条件:一、对于整个序列,左括号数量等于右括号;二、对于任意前缀,左括号的数目都不小于右括号的数目。岛娘想知道,对于一串括号字符串,有多少子串是合法的,你能帮助她么。

输入

输入数据仅一行,包含一个长度为 n (1?≤?n?≤?106) 的括号字符串。

输出

输出一行,表示合法的括号子串的数目。

样例输入
(()())
样例输出
4
          思路:左括号数目等于右括号数目,而且到每个位置左括号数大于等于右括号数其实就是合法括号串。可以枚举每个右括号,到目前连续的合法匹配括号的数目。到当前右括号连续的合法括号的的数目等于到与其匹配的左括号的前一个括号的连续合法括号的数目+1。最后累加起来就是answer。
代码时间到:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 1e6+100;
typedef long long LL;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
int dp[maxn];
int id[maxn];
char str[maxn];
int main()
{
	memset(dp,0,sizeof dp);
//	memset(sum,0,sizeof sum);
	int i,j,k;
	scanf("%s",str+1);
	int l=strlen(str+1);
	LL ans=0;
	int sum=0;
	int tmp=0;
	for(i=1;i<=l;i++){
		if(str[i]=='('){
			id[tmp++]=i;
		}
		else
		{
			if(tmp>0){
				tmp--;
				sum=dp[id[tmp]-1]+1;
				dp[i]=sum;
				ans=ans+sum;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

WA代码:

WA 的样例:((())(())) 输出7 正确答案是6 。括号序列经常容易忽略在()(())类似的括号序列。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 1e6+100;
typedef long long LL;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
int dp[maxn];
char str[maxn];
int main()
{
	memset(dp,0,sizeof dp);
//	memset(sum,0,sizeof sum);
	int i,j,k;
	scanf("%s",str+1);
	int l=strlen(str+1);
	LL ans=0;
	int sum=0;
	int tmp=0;
	for(i=1;i<=l;i++){
		if(str[i]=='('){
			dp[i]=0;
			sum=0;
			tmp++;
		}
		else
		{
			if(tmp>0){
				sum=dp[i-2-sum*2]+1;
				dp[i]=sum;
				ans=ans+sum;
			}
			tmp--;
			tmp=max(tmp,0);
		}
	}
	cout<<ans<<endl;
	return 0;
}
时间: 2024-10-12 15:05:39

hihoCoder 1300 展胜地的鲤鱼旗 (括号匹配问题 dp)的相关文章

hihocoder 20 展胜地的鲤鱼旗

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 岩手县北上市的「北上市立公园展胜地」,是陆奥国三大樱花名所之一.每年的四月中旬到五月初,这里都会举办盛大的祭奠.除了可以在盛开的樱花步道上乘坐观光马车徐行.还有横跨北上川上的鲤鱼旗,河畔还有当地特有的为祭奠祖先而编创的北上鬼剑舞. 假设,我们用一个包含 '(', ')'的括号字符串来区别每面鲤鱼旗的方向.一段括号序列被称为合法的,当且仅当满足两个条件:一.对于整个序列,左括号数量等于右括号:二.对于任意前缀,左括号的数

[HIHO1300]展胜地的鲤鱼旗(栈,dp)

题目链接:http://hihocoder.com/problemset/problem/1300 给一个字符串,只包含'('和')',问存在多少个子串似的括号是匹配的. 匹配规则在题干中描(蒻)述(语)得(文)非常烂! 维护一个栈,栈中保存'('的下标.当遇到')'并且栈非空的时候,说明已经匹配到一对括号.取出栈顶'('的位置idx.并且记录此时状态,dp(i)=dp(idx-1)+1. 1 #include <algorithm> 2 #include <iostream> 3

题目2 : 展胜地的鲤鱼旗 (hihoCoder挑战赛20 )

题目2 : 展胜地的鲤鱼旗 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 岩手县北上市的「北上市立公园展胜地」,是陆奥国三大樱花名所之一.每年的四月中旬到五月初,这里都会举办盛大的祭奠.除了可以在盛开的樱花步道上乘坐观光马车徐行.还有横跨北上川上的鲤鱼旗,河畔还有当地特有的为祭奠祖先而编创的北上鬼剑舞. 假设,我们用一个包含 '(', ')'的括号字符串来区别每面鲤鱼旗的方向.一段括号序列被称为合法的,当且仅当满足两个条件:一.对于整个序列,左括号数量等于右括号:

hihocoder-1300 展胜地的鲤鱼旗(dp)

展胜地的鲤鱼旗 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 岩手县北上市的「北上市立公园展胜地」,是陆奥国三大樱花名所之一.每年的四月中旬到五月初,这里都会举办盛大的祭奠.除了可以在盛开的樱花步道上乘坐观光马车徐行.还有横跨北上川上的鲤鱼旗,河畔还有当地特有的为祭奠祖先而编创的北上鬼剑舞. 假设,我们用一个包含 '(', ')'的括号字符串来区别每面鲤鱼旗的方向.一段括号序列被称为合法的,当且仅当满足两个条件:一.对于整个序列,左括号数量等于右括号:二.对于任意

poj 2955 Brackets 括号匹配 区间dp

题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+2), a[k]与a[j] 匹配,结果一组数据出错 ([]]) 检查的时候发现dp[2][3]==2,对,dp[2][4]=4,错了,简单模拟了一下发现,dp[2][4]=dp[2][1]+dp[2][3]+2==4,错了 此时2与4已经匹配,2与3已经无法再匹配. 故转移方程改为dp[i][j]=

poj2955括号匹配 区间DP

类似于上一篇博文. #include<stdio.h> #include<string.h> const int maxn = 120; char s[maxn]; int dp[maxn][maxn]; int max(int x,int y) { return x>y?x:y; } int main() { int i,j,k; while(scanf("%s",s)) { if(strcmp(s,"end")==0) break;

[poj2955]括号匹配(区间dp)

解题关键:了解转移方程即可. 转移方程:$dp[l][r] = dp[l + 1][r - 1] + 2$ 若该区间左右端点成功匹配.然后对区间内的子区间取max即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 using namesp

nyoj 括号匹配

这个方程有两种形式,本文采用 if(s[i]=s[j]) dp[i][j]=d[i-1][j-1] dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]) (i=<k<j) 其实与另一种方法比较:根据j的所有匹配情况取最小值 1.i到j无匹配,取为dp[i][j-1]+1 2.列举所有匹配情况 dp[i][k-1]+dp[k+1][j] 取上述所有情况最小值 两者都能获得正确的结果. 同时两者的初始化为 dp[i][j]==1 if(i==j) 规划方向为:  

括号匹配问题(顺序栈实现)

本周老师作业留了两个.先上传一个吧.那个有时间我再传上来~ 本周的要求: 1.给出顺序栈的存储结构定义. 2.完成顺序栈的基本操作函数. 1)      初始化顺序栈 2)      实现入栈和出栈操作 3)      实现取栈顶元素和判空操作 括号匹配问题 3.编写主函数实现基本操作函数功能,并设置测试数据,测试合法和非法数据的输出结果. 4.程序调试运行并保存输出结果. 5.整理并提交实验作业. 1 #include <cstdio> 2 #include <cstring>