NKOJ P1507 做错的作业

问题描述

小影(人名) 的数学作业错误百出.
老师:“你作业的表达式里面只有n个括号,怎么就写错了这么多?”
“n那么大,都到300了。”
老师:“那第一个小题只有一个括号你都写错了,这怎么解释?你看,你就写了一个‘(’,明显漏掉了一个‘)’吧?”
“这……”小影似乎很清楚的记得自己是写的“()”,可是现在怎么只剩下“(”了呢?
老师:“你看别人某某,写的多好?十道题都做对了。这样吧,我不看你的计算结果了,只看你的括号匹配得正不正确,你今天之内把你的括号修改正确就可以了……”
“嘿嘿……我把括号全部划掉不就全对了?”小影阴险地想。
老师:“……不过有一个条件:你只能添加括号而不能把括号划掉,并且你只能添加最少数量的括号。”
“天呐!”小影瘫倒了,要知道十个题目里面只有第一题很简单,其他的题目括号数目是巨多的。
看来,只能请善良的你帮帮小影了。

输入格式

只有一行,为一个长度为n的字符串,代表小影作业中写的括号。其中有4类括号“()”“[]”“<>”“”,“(”和“)”匹配,“[”和“]”匹配,“<”和“>”匹配,“{”和“}”匹配,左括号必须在左,右括号必须在右,其他组合是不匹配的。两个匹配的括号中间可以夹有其他已经匹配的括号。如“([<>])()”就是匹配的。

输出格式

一个整数,为小影最少需要添加的括号数目。

样例输入 1

([(]{})(<>))

样例输出 1

2

样例输入 2

[]>][>]<({[]]{<){{{(})

样例输出 2

12

样例输入 3

[]>][>]<({[]]

样例输出 3

7

这道题很类似于nkoj的另一道题 括号匹配 

 思路,先输入一个字符串/字符数组,然后初始化一个f数组

通过找规律的方式可以得到

当一个括号匹配时

只需要

f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j-1]);  

就可以计算,最后得出的f[1][n]就是答案。

计算括号是否是否匹配的方式有多种

这里选择:

int juge(int k,int j) {
	bool p;
	p=0;
	if(a[k]=='('&&a[j]==')')	p=1;
	if(a[k]=='['&&a[j]==']')	p=1;
	if(a[k]=='{'&&a[j]=='}')	p=1;
	if(a[k]=='<'&&a[j]=='>')	p=1;
	if(p==1)	return 1;
	return 0;
}

对了,还需要特殊判断一下a长度小于2的情况 

总体的代码在这里(三处错误):

#include <bits/stdc++.h>
using namespace std;
long long f[5005][5005],n,ans,sum[5005];
char a[1000];
int juge(int k,int j) {
	bool p;
	p=0;
	if(a[k]=='('&&a[j]==')')	p=1;
	if(a[k]=='['&&a[j]==']')	p=1;
	if(a[k]=='{'&&a[j]=='>')	p=1;
	if(a[k]=='<'&&a[j]=='>')	p=1;
	if(p==1)	return 1;
	return 0;
}
int main() {
	scanf("%s",a+1);
	n=strlen(a+1);
	for(int i=n; i>=1; i--) {
		for(int j=i; j<=n; j++) {
			f[i][j]=f[i][j-1]+1;
			for(int k=i; k<j; k++) {
				if(juge(k,j)==0)	f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j-1]);  
			}
		}
	}
	else	cout<<f[1][n]<<endl;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值