【Codeforces 3D】Least Cost Bracket Sequence

Codeforces 3 D

题意:有一个括号序列,其中一些位置是问号,把第\(i\)个问号改成(需要\(a_i\)的代价,把它改成)需要\(b_i\)的代价。

问使得这个括号序列成立所需要的最小代价。

思路1:

这个是正统的贪心。

首先我们假设所有的位置上都是),那么我们在从左向右扫描的途中会发现一些问题。

比如:我们原来的序列是(??),现在假设成了())),那么在第三个字符处就会发现我们的打开的左括号数量为\(-1\),这是肯定不行的,所以我们必须把第二个字符或者第三个字符改成左括号以把左括号数量变成\(1\)。

那么就可以想出一个贪心的方案了:

我们从左向右扫描,如果把当前的问号改成右括号不会使打开的左括号数量出现问题,那么我们就把这个问号待定成右括号;

然后如果出现了问题,我们肯定要把所有的待定问号(包括当前这个)中改动代价最小的改成左括号。

这样我们就可以把左括号数量重新加成正的。

然后我们怎么维护代价最小的待定问号呢?直接用一个优先队列或者一个\(set\)就可以了。

思路2:

这个是过不了的\(dp\)。

我们肯定是考虑到了第\(i\)位,打开的左括号数量是\(j\),最小的代价。记为\(f(i,j)\)。

然后我们考虑转移。如果是左括号,那么转移到\(f(i+1,j+1)\),右括号,转移到\(f(i+1,j-1)\),问号,都要转移,同时加上代价。

可惜,这样会\(mle\)或\(tle\)。

所以考虑优化状态。(转移怎么优化啊。。。

首先我们记如果把从\(i\)开始的所有问号都改成右括号,会把打开的左括号数量减少多少为\(suf_i\)。

那么如果\(j>suf_i\),即所有的一起上都消不掉\(j\),或者\(j\not \equiv suf_i (mod\ 2)\),即把一些右括号改成左括号不可能消掉\(j\),那么这个状态就不要。

可惜这样还是会在第\(31\)个点上挂掉。

思路3:

这个是乱搞的线段树。

ly_61同学提出了用数据结构来优化贪心的方法,然后。。。

首先我们考虑把所有的问号都改成左括号。

然后把所有的问号的左括号改成右括号的代价从小到大排序。

然后按顺序一个个尝试把问号改成右括号,只要不会违背条件——在任何一个位置,这个位置为止打开的左括号数量大于等于\(0\)。

那么我们就可以用线段树来维护对于每一个位置打开的左括号数量。

我们把一个问号改成右括号所改变的是把从那个问号的位置开始一直到最后的所有位置的左括号数量\(-2\)。

改回来的代价是\(+2\)。(废话

然后就可以一个一个尝试辣

如果改到最后发现到最后那个位置的左括号数量不是\(0\),那肯定无解。

这个正确性不是那么显然,但最优性显然。下证正确性。

首先如果把所有的问号都改成左括号时到最后一位的打开的左括号数量不是偶数,则肯定无解。

那么我们需要改的问号的数量也是显然的,不妨记其为\(m\)。

然后就可以发现如果我们每一次修改都可以成功的话至多修改\(m\)个问号。

那么就要证最少修改\(m\)个问号了。

我才不会告诉你我不会证了呢

根据上文,至少有\(m\)个问号使得我们把它们都改成右括号之后可以满足要求

所以我们扫描之后就可以得到\(m\)个???

(其实这个正确性很迷辣。。。

(这个“证明”一点也不像是个证明辣。。。

(反正能过的方法就是好方法。。。

(其实可能有反例的吧。。。

原文地址:https://www.cnblogs.com/denverjin/p/10591123.html

时间: 2024-08-01 19:32:33

【Codeforces 3D】Least Cost Bracket Sequence的相关文章

【 CodeForces - 392C】 Yet Another Number Sequence (二项式展开+矩阵加速)

Yet Another Number Sequence Description Everyone knows what the Fibonacci sequence is. This sequence can be defined by the recurrence relation: F1 = 1, F2 = 2, Fi = Fi - 1 + Fi - 2 (i > 2). We'll define a new number sequence Ai(k) by the formula: Ai(

【CodeForces 438D 】The Child and Sequence

题意 要求支持三种操作  1.区间求和  2.单点修改  3.区间取模 分析 问题主要在于区间取模 需要多维护一个区间最大值,当最大值已经小于模数的时候就不需要操作了 [先开始读错题了,写了个区间修改哎我没救了] #include<bits/stdc++.h> using namespace std; #define N 110000 #define ll long long #define lc (p<<1) #define rc (p<<1|1) #define m

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

【codeforces 415D】Mashmokh and ACM(普通dp)

[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=2000),问满足[数列长度是k && 数列中每一个元素arr[i]在1~n之间 && 数列中元素可以重复]的数列有多少个?结果对10^9+7取余 解题思路:dp[i][j]表示长度是j,最后一位是i的种数 if(kk%i==0) dp[kk][j+1]+=dp[i][j] 1 #i

【Unity 3D】学习笔记四十二:粒子特效

粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起,来模拟火焰,爆炸,水滴,雾气等效果.要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system即可 粒子发射器 粒子发射器是用于设定粒子的发射属性,比如说粒子的大小,数量和速度等.在创建完粒子对象后,在右侧inspector视图中便可以看到所有的粒子属性: emit:是否是使用粒子发射器. min size:粒子最小尺寸. max size:粒子最大尺寸. min energy:粒子的最小生命周期

【Unity 3D】学习笔记三十四:游戏元素——常用编辑器组件

常用编辑器组件 unity的特色之一就是编辑器可视化,很多常用的功能都可以在编辑器中完成.常用的编辑器可分为两种:原有组件和拓展组件.原有组件是编辑器原生的一些功能,拓展组件是编辑器智商通过脚本拓展的新功能. 摄像机 摄像机是unity最为核心组件之一,游戏界面中显示的一切内容都得需要摄像机来照射才能显示.摄像机组件的参数如下: clear flags:背景显示内容,默认的是skybox.前提是必须在render settings 中设置天空盒子材质. background:背景显示颜色,如果没

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

【Unity 3D】学习笔记三十七:物理引擎——碰撞与休眠

碰撞与休眠 上一篇笔记说过,当给予游戏对象刚体这个组件以后,那么这个组件将存在碰撞的可能性.一旦刚体开始运动,那么系统方法便会监视刚体的碰撞状态.一般刚体的碰撞分为三种:进入碰撞,碰撞中,和碰撞结束.关于休眠可以理解成为让游戏对象变成静止状态.如果给某个游戏对象休眠的状态,那么这个物体将立马静止,不再运动. 碰撞 首先学习下碰撞几个重要的方法: OnCollisionEnter(  ):刚体开始接触的时候,立即调用. OnCollisionStay(  ):碰撞过程中,每帧都会调用此方法,直到撞