括号

区间和序列上的dp

懵懂的女人 提交于 2019-12-03 13:06:05
区间上的dp状态设计最基本的形式: \(F[i]\) 表示以i结尾的最优值或方案数。 \(F[i][k]\) 表示以i结尾附加信息为k的最优值或方案数。 当然可以有多维附加信息。 转移的话往往是枚举上一个断点。 \(F[i]=max \{ F[j]+ w(j+1,i) | j是一个满足转移条件的断点\}\) 。 另一个很常见的是:$ f[i][j]$前i个位置分成j段/选出j个的最优值。 这是最简单的一类序列上的dp bzoj1003 有m个码头和e条航线,每天航线有成本。有连续n天需要从1号码头到m号码头运输货物。每个码头会在某些天数区间内不许经过。每更换一次运输路线,要付出k的成本。 求这n天的最小总成本。 m<=20, n<=100 SOLUTION: 其实就是分成很多段,每一段选同一个运输路线,然后得到一个最优的划分方案,使得成本最小。 f[i]表示前i天的运输最小成本。 \(f[i]=min\{ f[j]+k+w(j+1,i)*(i-j) | j<i \}\) 其中w(x,y)表示最短的在第x天到第y天都能用的路线长度; 处理方法: 首先枚举所有的x,y,然后利用最短路算法(这里dijkstra)算出x~y这些天都可以满足的1到m的最短路径;(计算方法:首先数组$use[i][j] $记录第i个点在第j天是否可以使用,在dijkstra时传入x和y,提前预处理

卡特兰数及其变形

二次信任 提交于 2019-12-03 04:56:53
题面 求n个左括号,n个右括号组成的所有序列中刚好有m对不匹配的序列总数. 分析 解法一 打表 打了2.5小时,几度自闭 解法二 易知m为0时答案即是卡特兰数,于是问题变成了合法序列个数的扩展问题。 回顾卡特兰数的证明,考虑折线法,从原点开始,遇见左括号斜向上画,遇见右括号斜向下画,所有线无论如何最后都会止于(2n,0)(因为向上向下次数一致),总数即是从原点到(2n,0)的方案数C(2n,n)(2n步中任取n步向上),m = 0要求左右括号完全匹配,则折线永远不能越过x轴(右括号过多不存在左括号与之匹配,不合要求)。要求合法序列个数可考虑合法 = 总数 - 不合法。刚才分析得越过x轴的线都不合法且不合法的线都必与y = -1相交,设第一次与y = -1相交的交点为k,将k以后的折线关于y = -1对称则必有(2n,0)对应(2n,-2),则不合法方案数转为从原点到(2n,-2),即等同于左括号比右括号少2个时的总方案数C(2n,n-1)(总数仍是2n,但有n-1个左括号,n+1个右括号)。 推广:由上分析知 至多m对不合法 = 总数 - 至少m + 1对不合法, 那么要求的 刚好m个 = 总数 - 至多m - 1对 - 至少m + 1对, 为C(2n,n) - (C(2n,n) - C(2n,n-m)) - C(2n,n-m-1); 推荐 组合数学—卡特兰数(catalan

括号生成

匿名 (未验证) 提交于 2019-12-03 00:39:02
对于这种列出所有结果的题首先还是考虑用递归Recursion来解,由于字符串只有左括号和右括号两种字符,而且最终结果必定是左括号3个,右括号3个,所以我们定义两个变量left和right分别表示剩余左右括号的个数,如果在某次递归时,左括号的个数大于右括号的个数,说明此时生成的字符串中右括号的个数大于左括号的个数,即会出现‘)(‘这样的非法串,所以这种情况直接返回,不继续处理。如果left和right都为0,则说明此时生成的字符串已有3个左括号和3个右括号,且字符串合法,则存入结果中后返回。如果以上两种情况都不满足,若此时left大于0,则调用递归函数,注意参数的更新,若right大于0,则调用递归函数,同样要更新参数。代码如下: vector< string > generateParenthesis( int n) { string out ; vector < string > res; generate(res,n,n, out ); return res; } void generate(vector< string >&res, int left, int right, string out ){ if (left== 0 &&right== 0 ){ res.push_back( out ); return ; } if (left>right) return ;

括号匹配问题

匿名 (未验证) 提交于 2019-12-03 00:30:01
http://pkuic.openjudge.cn/hw07/4/ 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用”$”标注,不能匹配的右括号用”?”标注. ###题目思路 (入栈,遇)出栈 #include <iostream> #include<stack> #include<string> using namespace std ; int main() { freopen( "in.txt" , "r" ,stdin); stack < int > st; string s; while (getline( cin ,s)){ cout <<s<<endl; for ( int i= 0 ;i<s.length();i++){ if (s.at(i)== '(' ){ st.push(i); s[i]= '$' ; } else if (s.at(i)== ')' ){ if (st.empty()){ s[i]= '?' ; } else { s[i]= ' ' ; int index=st.top(); s[index]= ' ' ; st.pop(); } }

NYOJ 括号配对问题

匿名 (未验证) 提交于 2019-12-03 00:30:01
没什么好说的,,是左括号进栈,右括号判断,就是容易出错注意细节 #include <iostream> #include <vector> #include <cstdio> #include <stack> using namespace std; int n; stack<char> s; vector<char> vec; char sign; int main() { cin>>n; getchar();//排除输入n的回车对后续输入的干扰 while(n--){ int flag = 1; while((sign=cin.get())!='\n'){ vec.push_back(sign); } for(int i=0;i<vec.size();i++){ if(vec[i]=='('||vec[i]=='['){ s.push(vec[i]); continue; } if(s.empty()){ flag=0; break; } char stop = s.top(); if(stop=='('&&vec[i]==')'||stop=='['&&vec[i]==']'){ s.pop(); } else { flag = 0; break; } } if(flag==1&&s.empty())cout<<"Yes"<<endl; else cout<<"No"<

[BZOJ2329]/[BZOJ2209]-括号修复-Splay维护信息

匿名 (未验证) 提交于 2019-12-03 00:19:01
好久没码过…已经码不动了 BZOJ2329传送门 BZOJ2209传送门 看题可戳传送门,2209是2329的简化版(虽然它们都是省选题) 这个题的难点在于 取反操作 和 翻转操作 的维护 取反操作 和 翻转操作 并不能像普通信息一样直接打tag,因为是不可以直接翻转的,举个例子: ( ( ( ( ) ) 反转变成了 ) ) ) ) ( ( ,如果直接取反显然GG,翻转也类似 原因是,我们在统计贡献的时候,实际采取的策略是:「从左到右,靠左多余右括号不可抵消」。即 ( ( ) ) 这样是可以抵消的,而反转之后的 ) ) ( ( 不行。这导致我们不能直接 反/翻转 但是我们可以发现,反转后的策略, 对于原序列的策略是 :「从左到右,靠左多余左括号不可抵消」。也就是说,反转之后的答案应该这样维护:原序列如果是 ) ) ( ( 则可以抵消的而 ( ( ) ) 不行。(翻转类似,翻转=反转再交换儿子,所以翻转和反转的策略一样) 那么我们需要维护一些东西,使得在策略发生改变之后,仍然可以得出答案 那么显然的方法就是,两种策略都维护 所以我们只需维护,左边最多连续左括号/右括号,右边最多连续左括号/右括号 即可 注意 反转 和 翻转 以及 覆盖 时的标记细节 然后这题就做完了 me采用的是 左括号-1,右括号+1,统计 lmin/lmax,rmin/rmax 的方式 本质和上面是一样的

20182332 实验⑥《数据结构与面向对象程序设计》实验报告

大兔子大兔子 提交于 2019-12-03 00:09:51
20182332 实验⑥《数据结构与面向对象程序设计》实验报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 盛国榕 学号:20182332 实验教师:王志强 实验日期:2019年10月28日 必修/选修: 必修 1.实验内容&实验过程&结果 链表练习,要求实现下列功能: (1)通过键盘输入一些整数,建立一个链表(1分); 这些数是你学号中依次取出的两位数。 再加上今天的时间。 例如你的学号是 20172301 今天时间是 2018/10/1, 16:23:49秒 数字就是 20, 17,23,1, 20, 18,10,1,16,23,49 打印所有链表元素, 并输出元素的总数。 在你的程序中,请用一个特殊变量名来纪录元素的总数,变量名就是你的名字。 例如你叫 张三, 那么这个变量名就是 int nZhangSan = 0; //初始化为 0. (2)实现节点插入、删除、输出操作(2分,3个知识点根据实际情况酌情扣分); 继续你上一个程序, 扩展它的功能,每做完一个新功能,或者写了超过10行新代码,就签入代码,提交到源代码服务器; 从磁盘读取一个文件, 这个文件有两个数字。 从文件中读入数字1, 插入到链表第 5 位,并打印所有数字,和元素的总数。 保留这个链表,继续下面的操作。 从文件中读入数字2, 插入到链表第 0 位,并打印所有数字,和元素的总数。 保留这个链表

BracketHighlighter括号高亮配置

匿名 (未验证) 提交于 2019-12-03 00:05:01
BracketHighlighter BracketHighlighter是一个用于成对括号(大括号、中括号、圆括号、尖括号)、引号等符号的高亮显示的插件 插件安装 首先打开package Control,选择install Package,之后输入BracketHighlighter,点击就可以了。 在安装完成之后,默认是这样显示的 默认其实已经比较好看了,但是还是不够好,按照下面的设置看看吧 点击Preference -> Package setting -> BracketHighlighter -> Bracket setting 把下面的复制粘贴到右边的用户设置中去 { // 这个是在成对的括号左侧显示一条竖线,表明开闭括号的范围与位置,如果不需要把true改为false “content_highlight_bar”: true, // 下面不同括号的显示方式,默认是下划线,这里改成了高亮 “bracket_styles”: { “default”: { “icon”: “dot”, “color”: “region.yellowish brackethighlighter.default”, “style”: “highlight” }, “unmatched”: { “icon”: “question”, “color”: “region.redish”,

正则表达式:引用分组

匿名 (未验证) 提交于 2019-12-03 00:03:02
分组的一个附加功能是 捕获分组,对应的括号叫做捕获括号。 括号分组的编号规则是从左到右,从一开始。 print re.search(r"(\d{4})-(\d{2})-(\d{2})"),"2010-12-22").gronp(1) 2010 默认认为存在编号为0的分组,全打印。 print re.search(r"(\d{4})-(\d{2})-(\d{2})"),"2010-12-22").gronp(0) 2010-12-22 分组编号取决于括号开始的顺序。 分组可以提取超链接的详细信息。 新手容易弄错的分组结构。 print re.search(r"(\d{4})-(\d{2})-(\d{2})"),"2010-12-22").gronp(1) 2010 print re.search(r"\d({4})-(\d{2})-(\d{2})"),"2010-12-22").gronp(0) 0 在替换中使用分组。 print re.sub(r"(\d{4})-(\d{2})-(\d{2})"), r"\1年\2月\3日", "2010-12-22") 2010年12月22日 反向引用: 用反向引用匹配成对的tag: 来源:博客园 作者: 风之领主 链接:https://www.cnblogs.com/lordwind/p/11508377.html

生成json文件写入本地

匿名 (未验证) 提交于 2019-12-02 23:57:01
public class Json { public static void main(String[] args) { String fullPath = null; //例如:fullPath="D:/myroot/test.json" // 生成json格式文件 try { // 保证创建一个新文件 File file = new File("E:\\json"); if (!file.getParentFile().exists()) { // 如果父目录不存在,创建父目录 file.getParentFile().mkdirs(); } if (file.exists()) { // 如果已存在,删除旧文件 file.delete(); } file.createNewFile(); //以下创建json格式内容 //创建一个json对象,相当于一个容器 JSONObject root = new JSONObject(); root.put("name", "张三"); root.put("age", 20); //假设身高是double,我们取小数点后一位 double height = 185.5345; root.put("height", (double) (Math.round(height * 10) / 10.0)); JSONArray array =