持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
虽然是C++组的,但是和Java组的差不了两道题,大家都可以看一看 如有错误,还请佬 评论或私信指出(写的稍些急) 再也不肝博客了 /(ㄒoㄒ)/~~
(由于上传图片有限制,如果描述不清楚点击手写题解) 手写题解字丑,但是小编感觉会比文字看的直观一些(其实是不会用数学公式)
C++B组手写题解(如果访问出错,请刷新访问的页面即可(Nebo的问题))
当前页面的编程题均在C语言网成功运行 C语言网有各届蓝桥杯的题库 第十二届蓝桥杯编程题测试 刷题集
试题 J: 括号序列
时间限制: 1.0s
内存限制: 256.0MB
本题总分:25 分
【问题描述】
给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,
当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。
两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括
号。
例如,对于括号序列 (((),只需要添加两个括号就能让其合法,有以下几
种不同的添加结果:()()()、()(())、(())()、(()()) 和 ((()))。
【输入格式】
输入一行包含一个字符串 s,表示给定的括号序列,序列中只有左括号和
右括号。
【输出格式】
输出一个整数表示答案,答案可能很大,请输出答案除以 1000000007 (即
109 + 7) 的余数。
【样例输入】
((()
【样例输出】
5
【评测用例规模与约定】
对于 40% 的评测用例,|s| ≤ 200。
对于所有评测用例,1 ≤ |s| ≤ 5000。
package LanqiaobeiExam._12CB;
import java.util.Scanner;
/**
* ClassName: J括号序列
* Package: LanqiaobeiExam._12CB
*
* @DATE: 2022/3/22 21:36
* Author: asleep
*/
public class J括号序列 {
static int MOD = 1000000007;
private static long calc(String s) {
int n = s.length();
long[][] dp = new long[n + 2][n + 2]; //+2 是因为dp状态转移方程需要 n+1的数(其实是懒得特判)
char[] str = s.toCharArray();
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
if (str[i - 1] == '(') {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][j - 1];
}
} else {
dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % MOD; //这一步用原状态转移式,新状态转移式子会越界
for (int j = 1; j <= n; j++) {
dp[i][j] = (dp[i - 1][j + 1] + dp[i][j - 1]) % MOD;
}
}
}
for (int i = 0; i <= n; i++) { //一定存在解,最差dp[n][n]也是解
if (dp[n][i] > 0) { // 其实有一种可能是dp本来有值,但是 %MOD 后为0,显然测试用例没有这种情况(如果有这种情况加个boolean数组记录一下即可)
return dp[n][i];
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int n = s.length();
long left = calc(s);
char[] str = new StringBuilder(s).reverse().toString().toCharArray();
for (int i = 0; i < n; i++) {
if (str[i] == '(') {
str[i] = ')';
} else {
str[i] = '(';
}
}
String ss = new String(str);
long right = calc(ss);
System.out.println(left * right % MOD);
}
}
#include <algorithm>
#include "iostream"
#include "cstring"
using namespace std;
const int N = 5010, MOD = 1e9 + 7;
int n;
char str[N];
int dp[N][N];
long calc() {
memset(dp, 0, sizeof dp);
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
if (str[i - 1] == '(') {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][j - 1];
}
} else {
dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % MOD;
for (int j = 1; j <= n; j++) {
dp[i][j] = (dp[i - 1][j + 1] + dp[i][j - 1]) % MOD;
}
}
}
for (int i = 0; i <= n; i++) {
if (dp[n][i]) {
return dp[n][i];
}
}
return -1;
}
int main() {
cin >> str;
n = strlen(str);
long left = calc();
int a = 10;
reverse(str, str + n);
for (int i = 0; i < n; i++) {
if (str[i] == '(') {
str[i] = ')';
} else {
str[i] = '(';
}
}
long right = calc();
cout << left * right % MOD << endl;
return 0;
}