problem1 link

首先去掉原串中已经配对的括号,那么剩下的括号序列是以下情况:(1)空串;(2)))));(3)((((;(4)))))((。第一种情况不需要处理。对于第三种情况和第四种情况,都可以将其变成第二种情况。第二种情况只需要对前一半做操作即可。另外,每次操作的时候不会影响已经删掉的匹配的串。

problem2 link

(1)首先,如果$[x,y_{1}],[x,y_{2}],y_{1}< y_{2}$都要是匹配的,那么有$[x,y_{1}],[y_{1}+1,y_{2}]$之间要分别匹配。

(2)其次,如果$[x_{1},y_{1}],[x_{2},y_{2}]$都要匹配,$x_{1}<x_{2}<y_{1}<y_{2}$,那么$[x_{1},x_{2}-1],[x_{2},y_{1}],[y_{1}+1,y_{2}]都要匹配$

经过这样的处理,最后所有匹配的区间可能会有包含的关系,然后没有其他相交关系。所以可以按照区间长度排序,一个区间一个区间进行处理。每个区间都相等于一个小的串(对于包含小区间的大区间不需要考虑已经处理的小区间,只需要考虑除了小区间外其他的部分匹配)。对于一个串$T$,定义$f(T)$表示将$T$变成匹配最少的修改数,这个修改指的是单独把左括号改成右括号或右括号改成左括号的次数,而不是交换。最后的答案其实是重复了一半,除以2即可。还有一个问题是有可能所有考虑的范围内的左括号数过于多,以至于在未考虑区间根本没有足够的右括号可以交换,这种情况是无解的。

problem3 link

这里有一个贪心的思路。

code for problem1

#include <algorithm>
#include <queue>
#include <string>
#include <vector> class ParenthesesDiv1Easy {
public:
std::vector<int> correct(std::string s) {
int n = static_cast<int>(s.size());
if (n % 2 == 1) {
return {-1};
}
return Dfs(s);
} std::vector<int> Dfs(std::string &s) {
int n = static_cast<int>(s.size());
std::deque<int> st;
for (int i = 0; i < n; ++i) {
if (s[i] == '(') {
st.push_back(i);
} else if (!st.empty() && s[st.back()] == '(') {
st.pop_back();
} else {
st.push_back(i);
}
}
if (st.empty()) {
return {};
}
std::vector<int> ans; for (size_t i = 0; i < st.size(); ++i) {
if (s[st[i]] == '(') {
int L = st[i];
int R = st.back();
ans.push_back(L);
ans.push_back(R);
Flip(s, L, R);
auto r = Dfs(s);
for (int x : r) {
ans.emplace_back(x);
}
return ans;
}
}
ans.push_back(st.front());
ans.push_back(*(st.begin() + st.size() / 2 - 1));
return ans;
} void Flip(std::string &s, int L, int R) {
std::reverse(s.begin() + L, s.begin() + R + 1);
for (int i = L; i <= R; ++i) {
if (s[i] == '(')
s[i] = ')';
else
s[i] = '(';
}
}
};

code for problem2

#include <algorithm>
#include <string>
#include <vector> class ParenthesesDiv1Medium {
public:
int minSwaps(const std::string &s, const std::vector<int> &L,
const std::vector<int> &R) {
int n = static_cast<int>(s.size());
int m = static_cast<int>(L.size()); std::vector<int> inside(n);
for (int i = 0; i < m; ++i) {
++inside[L[i]];
if (R[i] + 1 < n) {
--inside[R[i] + 1];
}
}
for (int i = 1; i < n; ++i) {
inside[i] += inside[i - 1];
} std::vector<std::vector<int>> ends(n);
for (int i = 0; i < m; ++i) {
ends[L[i]].emplace_back(R[i]);
}
std::vector<std::pair<int, int>> requests;
for (int i = 0; i < n; ++i) {
if (ends[i].empty()) {
continue;
}
std::sort(ends[i].begin(), ends[i].end());
ends[i].erase(std::unique(ends[i].begin(), ends[i].end()), ends[i].end()); for (size_t j = 1; j < ends[i].size(); ++j) {
ends[ends[i][j - 1] + 1].emplace_back(ends[i][j]);
}
ends[i].resize(1);
int x = ends[i][0];
for (int j = n - 1; j > i; --j) {
if (!ends[j].empty() && ends[j].back() >= ends[i][0]) {
x = min(x, j - 1);
}
}
if (x < ends[i][0]) {
ends[x + 1].emplace_back(ends[i][0]);
ends[i][0] = x;
}
requests.emplace_back(i, ends[i][0]);
} int ans = 0;
std::sort(requests.begin(), requests.end(),
[&](const std::pair<int, int> &a, const std::pair<int, int> &b) {
int ll = a.second - a.first;
int rr = b.second - b.first;
return ll != rr ? ll < rr : a.first < b.first;
});
std::string cs = s;
for (const auto &e : requests) {
int ll = e.first;
int rr = e.second;
std::string cur_s;
for (int j = ll; j <= rr; ++j) {
if (cs[j] != '*') {
cur_s += cs[j];
cs[j] = '*';
}
}
int c = Compute(cur_s);
if (c == -1) {
return -1;
}
ans += c;
}
if (total_left > total_len) {
ans += total_left - total_len;
} else {
ans += abs(total_right - total_len);
}
for (int i = 0; i < n; ++i) {
if (inside[i] == 0) {
if (s[i] == ')') {
--total_left;
} else {
--total_right;
}
}
}
if (total_left > total_len || total_right > total_len) {
return -1;
}
return ans / 2;
}
int Compute(const std::string &s) {
int n = static_cast<int>(s.size());
if (n % 2 == 1) {
return -1;
}
if (n == 0) {
return 0;
}
auto Update = [&](int &x, int y) {
if (x == -1 || x > y) {
x = y;
}
};
std::vector<std::vector<int>> dp(n, std::vector<int>(n + 1, -1));
dp[0][1] = s[0] == ')';
for (int i = 1; i < n; ++i) {
for (int j = 0; j <= i; ++j) {
if (dp[i - 1][j] == -1) {
continue;
}
if (s[i] == '(') {
Update(dp[i][j + 1], dp[i - 1][j]);
if (j > 0) {
Update(dp[i][j - 1], dp[i - 1][j] + 1);
}
} else {
if (j > 0) {
Update(dp[i][j - 1], dp[i - 1][j]);
}
Update(dp[i][j + 1], dp[i - 1][j] + 1);
}
}
}
for (char x : s) {
if (x == '(') {
++total_left;
} else {
++total_right;
}
}
total_len += n / 2;
return dp[n - 1][0];
} int total_left = 0;
int total_right = 0;
int total_len = 0;
};

code for problem3

#include <string>

class ParenthesesDiv1Hard {
public:
int minCost(const std::string &s) {
int len = static_cast<int>(s.size());
std::string red, blue;
int r_num = 0, b_num = 0;
for (int i = 0; i < len; ++i) {
if (s[i] == '(') {
if (r_num == b_num) {
++r_num;
red += s[i];
} else {
++b_num;
blue += s[i];
}
} else {
if (r_num > b_num) {
red += s[i];
--r_num;
} else if (b_num == 0) {
return -1;
} else {
blue += s[i];
--b_num;
}
}
}
if (r_num != 0 || b_num != 0) {
return -1;
}
return Score(red).second + Score(blue).second;
} std::pair<int, int> Score(const std::string &s) {
int left = 0;
for (size_t i = 0; i < s.size(); ++i) {
if (s[i] == '(') {
++left;
} else if (--left == 0) {
auto score1 = Score(s.substr(1, i - 1));
auto score2 = Score(s.substr(i + 1));
int depth = std::max(score1.first + 1, score2.first);
int score = score1.second + (score1.first + 1) * (score1.first + 1) +
score2.second;
return {depth, score};
}
}
return {0, 0};
}
};

  

topcoder srm 688 div1 -3的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. Linux 切换用户

    Linux用户之间切换 在linux操作系统中,用户之间的切换使用,su 命令.linux系统环境中的用户信息如下: 用户名 角色 备注 root 管理员 root用户下配置的jdk 版本为:1.8 ...

  2. unity之让obj旋转自转等操作

    1.让cube沿着矩形四个点运动 using System.Collections; using System.Collections.Generic; using UnityEngine; publ ...

  3. Bootstrap-全局样式的文本颜色和背景颜色

    .text-五种颜色   文本颜色.text-info文本浅蓝颜色-提示.text-warning文本黄色-警告颜色.text-success文本绿色-成功颜色.text-primary文本深蓝色-警 ...

  4. Javascript-数据类型转换 、 运算符和表达式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. WinPE引导硬盘安装64位的Windows_Server_2008系统

    用 U盘WinPE引导实现硬盘安装Windows Server 2008 R2系统的方法如果想不用光盘(光盘和光驱总是靠不住的),只用U盘或移动硬盘上的WinPE引导,在电脑硬盘安装一个64位的Win ...

  6. oracle将unix 时间戳转换为date类型

    select to_date('19700101','yyyyMMdd')+numtodsinterval(8*3600,'second')+numtodsinterval(60,'second') ...

  7. SQLAllocHandle

    函数定义: 顾名思义,该函数就是用来分配句柄的,句柄类型参考参数详解. SQLRETURN SQLAllocHandle( SQLSMALLINT     HandleType, SQLHANDLE  ...

  8. Python全栈-day2-day3-语法基础1

    1.什么是变量,为什么需要变量 变量即变化的量,衡量现实中实物的状态:程序执行的本质就是一系列的状态变化,变是程序本身执行的直接体现,因此程序的执行需要这种机制将执行状态以及状态的变化保存下来. 1) ...

  9. python_super注意事项

    class room: def __init__(self,area=120,usedfor='sleep'): self.area = area self.usedfor = usedfor def ...

  10. maven 核心概念

    1). 项目构建过程中的各个环节 . 清理 . 编译 . 测试 . 报告 . 打包 . 安装 . 部署 2). 配置环境变量 . 配置 JDK 配置 JAVA_HOME + PATH maven 需要 ...