Codeforces 1152D DP】的更多相关文章

题意:有一颗由长度为2 * n的合法的括号序列构成的字典树,现在你需要在这颗字典树上选择一些不连接的边,问最多可以选择多少条边? 思路:不考虑题目条件的话,我们只考虑在随意的一棵树上选择边,这是一个贪心的问题,只需要每次选择叶子结点和它的父亲这条边,然后把它和它父亲节点删除就可以了,不断进行这个操作,就可以得到最终的答案.但是题目中的这颗字典树的规模是非常大的,不能用正常的方法.我们发现这颗字典树有2个性质: 1:这颗字典树的所有叶子结点都在同一层. 2:有很多的子树是重复的. 通过第一个性质以…
题目链接: https://codeforces.com/contest/1152/problem/D 题意: 给出一个$n$,然后在匹配树上染色边,每个结点的所有相邻边只能被染色一次. 问,这颗树上最多染色多少边. 匹配树,就是深度为$2n$的树,每个节点都是一个字符串,只包含$(,)$,以长度为$2n$的合法匹配字符串作为叶子.每个节点的父亲是比自身长度小一的节点. 数据范围: $1 \le n \le 1000$ 分析: 在百度找了很久都没找到满意的题解,于是看了cf给的官方题解.虽然是全…
大意: 将所有长度为2*n的合法括号序列建成一颗trie树, 求trie树上选出一个最大不相交的边集, 输出边集大小. 最大边集数一定不超过奇数层结点数. 这个上界可以通过从底层贪心达到, 所以就转化为求奇数层结点数. 然后就dp求出前$i$为'('比')'多j个的方案数, 奇数层且合法的时候统计一下贡献即可. #include <iostream> #include <iostream> #include <algorithm> #include <cstdio…
要点 寻找最多边的匹配的结论:贪心地从叶子开始找,最后答案都是奇数层下边的那条边. 设\(dp[i][j]\)表示当前长度为\(i\),平衡度为\(j\),平衡度为(数量减去)数量. 增加左右括号转移,并将奇数层合法的加到ans中. #include <cstdio> const int maxn = 1005, mod = 1e9 + 7; int n; long long dp[maxn << 1][maxn << 1], ans; int main() { sca…
https://codeforces.com/problemset/problem/813/D dp[i][j] = 一条链以i结尾, 另一条链以j结尾的最大值 关键要保证转移时两条链不能相交 #include <iostream>#include <cstdio> #define REP(i,a,n) for(int i=a;i<=n;++i) using namespace std; , M = 1e7+; int n; int a[N], dp[N][N], x[M],…
Consecutive Subsequence CodeForces - 977F 题目大意:输出一序列中的最大的连续数列的长度和与其对应的下标(连续是指 7 8 9这样的数列) 解题思路: 状态:把dp[i]定义为数列末尾为 i 的最大连续数列的长度值 状态转移方程:dp[i] = dp[i-1] + 1 再由最大连续数列最后一个值从后往前倒推出前面的所有值,到不是连续时停止 代码: #include<bits/stdc++.h> using namespace std; + ; int d…
1.(467C)http://codeforces.com/problemset/problem/467/C 题意:有一个长为n的序列,选取k个长度为m的子序列(子序列中不能有位置重复),求所取的k个序列求和的最大值是多少 分析:设dp[i][j]在[j,n]范围内取了i个子序列求和所得的最大值,用sum[i]表示[1,i]的求和.转移方程为dp[i][j]=max(dp[i-1][j+m]+sum[j+m-1]-sum[j-1],dp[i][j+1]),表示要不要选择[j,j+m-1]这段为其…
说明 Catalan(i) 表示卡特兰数的第 i 项. 题目链接:http://codeforces.com/problemset/problem/1152/C 题目大意 有 n 个左括号和 n 个右括号,它们一共可以组成 Catalan(n) 个合法括号字符串,把这些字符串组建成 Trie 树,求这棵树的二分图最大匹配. 分析 设 Node(L, R) 表示 Trie 树的一个节点,这个节点含有 L 个左括号和 R 个右括号. 虽然说是求二分图最大匹配,不过这道题却不能用求最大匹配的的方法求(…
/* 题意:给你一个有向无环图.给一个限定t. 问从1点到n点,在不超过t的情况下,最多可以拜访几个点. 保证至少有一条路时限不超过t. 思路: 1.由无后向性我们可以知道(取决于该图是一个DAG),这题一定可以dp. 2.dp[i][j]代表,到达点i,并且拜访了j个城市的最短时间. wa点: 没有初始化数组中的0.. */ #include<bits/stdc++.h> #define N 5050 using namespace std; int inf=0x3f3f3f3f; int…
题目:这里 题意:给定n个字符串,每个字符串可以进行一项操作,就是将这个字符串交换,就是该字符串的第一个和最后一个交换,第二个和倒数第二个交换,以此类推,当然可以选择对于 该字符串进行或不进行这项操作,而每个字符串都有一个相应的能量值,进行操作了就要消耗那么多能量值,最后是否能在消耗的能量值最小的情况下保证这些字符串是升序的( 字典序从小到大),不能就输出-1. 字符串用string,DP,dp[i][j]表示到第i个字符串的状态为j的时候(j为1表示这个串交换了,j为0表示这个串没有交换),注…
/* 题意:给一个长度不超过5000的字符串,每个字符都是0到9的数字. 要求将整个字符串划分成严格递增的几个数字,并且不允许前导零. 思路: 1.很开心得发现,当我在前i个区间以后再加一个区间的时候,转移 的条件只跟最后一个区间的数字大小有关,这决定这道题可以dp... 2.dp[i][j]代表前j个字符,最后划分的区间的第一个字符是第i个的答案数. 3.可知对于所有的dp[i][i...n]他们的答案都取决与dp[1...i-1][i-1]. 4.很容易想到对于同一个i,累加求得dp[i][…
/* 我是一个习惯后悔,但是没办法忍受内疚感的二货== 这题是个无脑dp,但是比赛大概20min没出...其实最后5min我好好想想简单化边界条件,可以出的. 题意: 给你一个长度为1e6的由?*01四种字符组成的字符串,类似扫雷,?代表当前不确定,0代表当前无雷,并且 两边无雷,1代表当前五雷且两边有一个雷,2同样的,问当所有格子已知以后一共有多少种可能的局面. 思路: 首先想到的是,这个问题无后效性,而当前位置的合法方式只与它之前的两位有关. 所以dp的思路也是显而易见的,即dp[i][j]…
题意: 有n天,m门课和常数k; 每天上一门课,每门课程有两个属性,最少作业量a,最多作业量b,和难度c. 1<=a<=b<=1e16 c<=100 1<=n<=m<=50 1<=k<=100 要求所有课程的作业量总和最多. 要求除第一天外,其他情况下作业量是前一天加k或者前一天乘k. 输出每天课程的序号,以及该课程应该布置的作业量. 思路: dp[i][j][k]代表第i门课,第j作业量,第k天的总和. 注意j是相对最少作业量的位移量. #inclu…
题目链接 题意: 对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望 思路: 将答案分为$3$部分 $1.$$-1$与$-1$之间对答案的贡献.由于逆序对考虑的是数字之间的大小关系,故假设$-1$的数量为$cnt$,可以等效成求长度为$cnt$的排列的逆序对期望.设$dp[i]$为长度为$i$的全排列的逆序对期望,有$dp[i]=dp[i-1]+$$\frac{i-1}{2}$,可以理解成在原$dp[i-1]$的基础上,数值$i$对每个长度为$i-1$的排列产生$\sum_{t=1}^{…
Game with Strings 题意并不是在图上走,看了好久才看出来.. dp[ i ][ mask ]表示从 i 层开始走,起点有mask个, a的个数-b的个数的  最大值或者最小值. #include<bits/stdc++.h> #define LL long long #define LD long double #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL&g…
大意: 给定序列, 每次操作可以任选一个数+1/-1, 求最少操作数使序列严格递增. 序列全-i后转化为求最少操作数使序列非降, 那么贪心可以知道最后$a_i$一定是修改为某一个$a_j$了, 暴力dp即可. #include <iostream> #include <cstdio> #define REP(i,a,n) for(int i=a;i<=n;++i) using namespace std; typedef long long ll; const int N =…
大意: 给定序列$a,b$, 每次可以任取两个相同大小的$a_i,b_j$删除$a_i,b_j$左侧所有元素, 花费为e, 得分1, 最后结束时必须再花费之前删除元素的个数, 不得分. 初始能量$s$, 求最大得分方案. 这题关键是注意到$\frac{s}{e}$的范围比较小, 直接暴力dp即可.. #include <iostream> #include <algorithm> #include <cstdio> #include <math.h> #in…
大意: 总共$n$的时间, $k$个红包, 红包$i$只能在时间$[s_i,t_i]$范围内拿, 并且拿完后时间跳到$d_i+1$,Bob采用贪心策略,每个时间点若有红包能取则取钱数$w_i$最大的, $w_i$相同则取$d_i$最大的, Alice有$m$次机会让Bob跳过一个时间, 求Alice如何操作能使Bob得到钱数最少. 比较简单的DP, 记$dp[i][j]$为$i$时刻还能干扰$j$次的最小收益 $dp[i][j]=min(dp[d_i][j]+w_i,dp[i+1][j-1])$…
大意: 给定一个m个bool变量的方程, 求方程解的个数 给定方程的形式类似于这样 每个括号是一个子式, 每个子式里变量数不超过2, 每个变量出现次数不超过2, 方程右侧一直是1 对每个变量出现的式子连边, 建好图后, 求出每个连通块内值为0或1的个数, 最后dp一下就能求出答案 考虑如何求每个连通块的答案, 因为每个点度数最多为2, 也就是说每个连通块只能为链或者简单环, 所以均可以dp求出 这题想法还是比较简单, 但具体实现还是不会了....以后还是要多练DP了…
题意: 房间着火了,里面有n件物品,每件物品有营救需要的时间t,被烧坏的最晚时间d,他的价值p,问能得到的最大价值,并且输出营救出来的物品编号 代码: //必然是先救存活时间短的即d小的,所以先排个序,dp[i][j]表示枚举到第i件物品时救出他的时间是j时的最大价值,然后就 //是取还是不取这件物品的问题了他的状态是由dp[i-1][~]转移来的.另外这题需要记录取了哪些物品,用g[i][j]表示第i件 //物品在j时间取没取,用pre数组记录前驱.输出还要按照取得顺序输出. #include…
题意:有2个人玩游戏,他们都有个初始值a和b, 游戏进行t轮, 每次可以选择加上一个[-k, +k]之间的数字,问有多少种方案a的和严格大于b的和. 思路:如果不考虑多于这个条件,只是询问有多少种方案的化,这是一个数塔模型的DP, 设dp[i][j]为到i位置,前面的数的和为j的方案数,直接转移即可.需要用前缀和优化.对两个人分别DP一次,然后枚举第一个人的最后的和,去找第二个人有多少个和小于它的方案.这个也需要用前缀和来优化. 代码: #include <bits/stdc++.h> #de…
题意:给你n个数,和一个数m, 问最小需要多少个数,可以让这些数乘起来是m的倍数.如果有多组,取和最小的那一组. 思路:因为m的范围到1e12,并且和取模相关,所以容易想到处理出m的约数,然后离散化一下,降低DP的第二维的复杂度,因为如果这些数的乘积不是m的约数,就没有意义了.dp[i][j]表示处理到第i个数,约数是j的最小个数.dp需要存pair,因为要求个数一样的时候和最小.可以提前把a和m求gcd以降低复杂度,注意特判m为1的情况. 代码: #include <bits/stdc++.h…
题意:给你一个字符串,这个字符串的构造方法如下:先选择一个长度大于4的前缀,然后每次向字符串尾部添加一个长度为2或者长度为3的后缀,不能添加连续的相同的后缀,问可能的后缀有哪些?并按字典序输出去. 思路:第一眼感觉要记忆化,设dp[i]表示把前i个字符作为前缀是否有合法方案,那么只有当前长度为2的串和后面的串重复了,长度为3的串和后面的串重复了,并且dp[i + 5]不合法,dp[i]才不合法.为什么呢?考虑这样一个样例: abcdezzzzzzzz, 合法的后缀有zz 和zzz, 我们可以让z…
题意:有一个人去买铲子,他需要买正好k把.每把铲子有个标价,并且每把铲子最多只能被买一次.有m种优惠方案,每个优惠方案xi, yi是指如果这次恰好购买了xi把铲子,那么这次购买的铲子中最便宜的yi把将免费.问买k把铲子的最少花费.题目可以分多次购买铲子,只要购买的铲子总数是k把就可以.买过的铲子就不能再买了. 思路:显然,我们需要先对铲子的售价排个序,然后实际上购买的铲子就是最便宜的k把铲子,因为题目中要求购买恰好k把铲子,不能多,所以不存在去购买多余的铲子去凑优惠这种方案.那么现在的问题就变成…
Gym - 100753J 某国家仅有金币和银币两种货币,起汇率为g,纪念品市场有n个商人和商品,商人结帐只用银币,并且把一堆银币装在袋子里,分为三种类型,分别按向下/向上/四舍五入取整(其中向上的优先使用银币交易),你要用c个金币买尽量多纪念品,输出最多纪念品数 细节较多的二维背包水题,差点没把我气死 注意不要把第三维改成纪念品数而答案为最多保留的银币数 不然无法处理generous的情况 https://paste.ubuntu.com/p/WNCSWc9rfs/ 407B 要求从节点1走到…
大意: 给定序列, 给定常数a,b, 两种操作, (1)任选一个长为$t$的子区间删除(不能全部删除), 花费t*a. (2)任选$t$个元素+1/-1, 花费t*b. 求使整个序列gcd>1的最少花费. 题目有个限制是不能全部删除, 所以最后一定剩余a[1]或a[n], 暴力枚举a[1]与a[n]的所有素因子即可. 这场div. 2题目感觉都挺简单的, 但实现起来各种出错...........各种细节还是没考虑好...... #include <iostream> #include &…
题目传送门:1519 拆方块 首先,我们可以发现,如果第i堆方块被消除,只有三种情况: 1.第i-1堆方块全部被消除: 2.第i+1堆方块全部被消除:(因为两侧的方块能够保护这一堆方块在两侧不暴露) 3.第i堆方块过了h[i]次操作后,从上到下被消除. 于是我们设l[i]为第i堆方块从左边开始消除的最小操作次数,设r[i]从右边开始消除的最小操作次数. 然后从左向右dp出l[i],从右向左dp出r[i],然后就能算答案了. 代码: #include<cstdio> #include<cs…
本着只贴代码不写分析的题解是在耍流氓的原则,还是决定写点分析. 思路很清晰,参考的官方题解,一下文字仅对题解做一个简要翻译. 题意: 有1~n这n个数,每个数用两次.构成一个长为2n的序列,而且要求序列满足先递增后递减(都是非严格的递增递减). 再给出k个约束,每个约束形如1 >= 3这种,表示序列的第一个数要不小于第三个数. 问满足约束的合法序列有多少种. 分析: 首先先不考虑这些约束条件,考虑如何构造出这种序列. 考虑两个1放置的位置,因为序列是两边小中间大,所以这两个1要么放在前面两个位置…
Jzzhu and Numbers Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-20) Description Jzzhu have n non-negative integers a1, a2, ..., an. We will call a sequence o…
D. Don't fear, DravDe is kind time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A motorcade of n trucks, driving from city «Z» to city «З», has approached a tunnel, known as Tunnel of Horror…