
--------------DP--------------
Lynstery
一只蒟蒻
展开
-
[树上依赖背包] BZOJ4910 LOJ2268: [SDOI2017] 苹果树
首先考虑 t−hmax≤kt-h_{max} \le k 的限制。可以看做除去最长到根链上的点各一个,剩下的最多取 kk 。 可以想到枚举叶子,求必选这个叶到根路径上各一个之后,其他取 kk 个的最大值。 普通的树上依赖背包一般是: 按后序遍历顺序 DPDP , fi,jf_{i,j} 表示后序遍历前 ii 个中选了 jj 个的最优解,后序遍历的好处是 ii 的子树内的点是 ii 前面的连续一原创 2017-12-14 19:52:17 · 754 阅读 · 0 评论 -
[杂题] Codeforces #121C. Lucky Permutation
这题很 cfcf 。虽然 nn 很大,但由于 KK 只有 1e91e9,所以数列前面大部分数字是在原位的。13!=622702080013!=6227020800,只有后面不到 1414 位会变化,后面暴力就好了。 前面的 11到 n−13n-13,数位 DPDP 求答案。#include<cstdio>#include<algorithm>using namespace std;const原创 2017-10-23 17:00:20 · 426 阅读 · 0 评论 -
[DP] BZOJ1090: [SCOI2003]字符串折叠
瞎区间DP。一个区间,要么是由两个直接接得,要么就是压缩起来。 直接 O(n4)O(n^4) #include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int maxn=105;char st[maxn];int n,f[maxn][maxn];int C原创 2017-10-12 16:23:04 · 383 阅读 · 0 评论 -
[DP] 51Nod1048 整数分解为2的幂 V2
这题是 51Nod1383 的升级版。nn 是103010^{30} 做法是神奇的 DPDP。在而二进制下考虑。 设 fi,jf_{i,j} 表示,组成2i2^i,用的最大数是 2j2^j 时的方案数。 转移就是 fi,j=fi−1,k+fi−1−k,j−kf_{i,j}=f_{i-1,k}+f_{i-1-k,j-k} 然后就是类似的每位合并。gi,jg_{i,j} 表示组成 nn 二进制下原创 2017-10-21 15:25:43 · 361 阅读 · 0 评论 -
[DP] ZROI 2017提高1 T2.给 Ca
DP状态的设计比较巧妙,考虑树按dfs序的顺序生成的过程,设 f[i][j]f[i][j] 表示放了 ii 个节点,根到当前节点向左走 jj 次,的方案数。 转移就是,再往左放一个,或者回到最近的向左走的节点的父亲,在右儿子位置放。 f[i+1][j+1]←f[i][j], f[i+1][j−1]←f[i][j]f[i+1][j+1] \leftarrow f[i][j],\ \ f[i+1]原创 2017-10-06 16:46:22 · 402 阅读 · 0 评论 -
[Lucas+数位DP] 2015 计蒜之道 复赛 C. 360的产品试用体验
就是Lucas+数位DP的套路。这题和一般的数位DP相比有个特别的限制是 x1+x2+x3≤nx1+x2+x3\le n,类似HNOI 2007《梦幻岛宝珠》的处理方法,即相当于借位,保存当前这位剩余的数,转移时乘P传给下一位。 有3个数要填,一开始我写的是每次转移一位,转移要O(473)O(47^3),结果T了。实际上应该每次转移一个数的一位,就好了。#include<cstdio>#incl原创 2017-10-11 16:07:41 · 446 阅读 · 0 评论 -
[SET维护DP] Codeforces #875E. Delivery Club
好题。首先不难想到二分答案。验证就是写出状态 n2n^2 的 DPDP,类似 二取一维数组 的搞法: fi,jf_{i,j} 表示前 ii 个点已走过,两个人分别在 ii 和 j, (i>j)j,\ (i>j) 。 fi,j→fi+1,j(ai+1−aj≤mid),fi,j→fi+1,i(ai+1−ai≤mid)f_{i,j} \rightarrow f_{i+1,j}(a_{i+1}-a_{j原创 2017-10-20 12:13:09 · 370 阅读 · 0 评论 -
[树形DP]「CEOI 2017 Practice」Museum
这是个比较显然的树形DP。即 f[i][j],g[i][j]f[i][j],g[i][j] 表示以 ii 为根的子树中,访问了 jj 个点,回到ii 和不必回到 ii 的代价。 转移的时候做类似背包一样的东西。一开始还以为这是暴力做法,实际上循环边界注意一下的话,实际复杂度是 O(n2)O(n^2) 的。相当于当儿子 vv 更新父亲 xx 时,花了 O((sz(x)−sz(v))∗sz(v))O((原创 2017-10-05 14:44:27 · 332 阅读 · 0 评论 -
[lucas+数位DP] 2017 计蒜之道 复赛 E. 商汤智能机器人
这题就是,把坐标斜一下看,相当于一个网格图,可以对角线走。如果不能对角线走就是经典的组合数了,所以我们可以尝试枚举经过多少条对角线边来写出答案的式子,设 A=x+y2,B=x−y2 A=\frac {x+y} 2,B=\frac {x-y} 2 , 则有ans=∑i=0B(A+B−ii)∗(A+B−2iA−i)ans=\sum_{i=0}^{B} {A+B-i \choose i}*{ A+B-2原创 2017-10-04 21:25:22 · 519 阅读 · 0 评论 -
[树形DP] 51Nod1500 苹果曼和树
简单的树形 DPDP 。记 fi,0/1f_{i,0/1} 表示考虑以 ii 为根的子树,所在的块有一个黑或没有黑结点的方案数。 转移很显然。#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int maxn=100005,maxe=100005,MOD=1000000007;原创 2017-10-19 10:04:59 · 397 阅读 · 0 评论 -
[杂题 DP] Codeforces 869C. The Intriguing Obsession
Obviously we’re not going to be able to connect the edges between the same color. The length of a routine like this: colorA -> colorB -> color C -> colorA, cannot exceed 3, so we only have to consider原创 2017-10-09 13:38:50 · 328 阅读 · 0 评论 -
[数位DP] Codeforces #809C. Find a car
好题。有一个不知道怎么得出来的结论:A(x,y)=(x−1) xor (y−1)+1A(x,y)=(x-1) \text{ xor } (y-1)+1 如果知道这个了就好做了,题目转换为求∑ni=0∑mj=0[i xor j≤K]∗(i xor j+1)\sum_{i=0}^n \sum_{j=0}^m [i\text{ xor }j \le K]*(i\text{ xor }j +1) 然后原创 2017-09-21 19:28:34 · 455 阅读 · 0 评论 -
[博弈 DP] BZOJ1783: [Usaco2010 Jan]Taking Turns
这个博弈比较简单,每个人的目标仅仅是让自己的分多。所以直接 DPDP 求: 设 fi,0f_{i,0} 表示 从 ii 开始取,先手最优值。fi,1f_{i,1} 是后手的最优值。 显然有 fi,0=max{aj+fj+1,1}f_{i,0}=max\{a_j+f_{j+1,1}\},fi,1=fpos,0f_{i,1}=f_{pos,0}。pospos 表示 fi,0f_{i,0} 是从哪里转原创 2017-10-31 16:26:19 · 438 阅读 · 0 评论 -
[DP] Codeforces #714E. Sonya and Problem Wihtout a Legend
不严格的比较简单,其实严格的可以转化成不严格的: i<j,aj−ai≥j−i⇔ai−i≤aj−ji<j,\quad a_j-a_i \ge j-i \Leftrightarrow a_i-i \le a_j-j 就是满足 ai−ia_i-i 不严格递增就好了。 不严格的做法就是直接 DPDP,改变的值肯定是原本就有的数,数的值范围是 O(n)O(n)。直接 fi,jf_{i,j} 表示前 ii原创 2017-11-09 11:26:14 · 414 阅读 · 0 评论 -
[DP] BZOJ2660: [Beijing wc2012]最多的方案
好题。fibfib 数不多,先都直接得到。注意到 fibfib 相邻数可以合并,所以我们就贪心的求出数最大的一组解,然后考虑把取来的数分裂。 设我们现在有一个fibifib_i,他能分裂成什么样呢? fibi=fibi−1+fibi−2=fibi−1+fibi−3+fibi−4=fibi−1+fibi−3+fibi−5+fibi−6fib_i=fib_{i-1}+fib_{i-2}=fib_{原创 2017-10-31 22:25:41 · 337 阅读 · 0 评论 -
[虚树 + DP] BZOJ2286: [Sdoi2011]消耗战
虚树入门题。 所谓虚树就是只保留需要的关键节点及互相的lca进行重建树,在虚树上跑DP之类的,是的复杂度之和关键点个数相关。 建虚树代码:void buildVT(){ inT.clear(); sort(S.begin(),S.end(),_cmp); stk[top=1]=1; inT.push_back(1); for(int i=0;i<S.size();i++)原创 2017-11-26 20:11:09 · 372 阅读 · 0 评论 -
[DP+AC自动机] BZOJ1212: [HNOI2004]L语言
直接 DPDP,fif_{i} 表示前 ii 个是否合法。fi|=fi−len(aj)(s[i−len(aj)+1]=aj)f_{i}|=f_{i-len(a_j)}(s[i-len(a_j)+1]=a_j) 用ACAC自动机加速转移的匹配过程。#include<cstdio>#include<queue>#include<algorithm>#include<cstring>using原创 2017-11-26 16:33:05 · 367 阅读 · 0 评论 -
[WQS二分套WQS二分] Codeforces #739E. Gosha is hunting
O(n3)O(n^3) DPDP 很显然。要优化就只能 WQSWQS 二分了。每种食物肯定是都用完的,所以相当于强制选若干个 AA 物品,若干个 BB 物品。发现物品选越多,收益是会增加的越来越慢的,所以这两维都可以 WQSWQS 二分。就能做到 O(nlog2n)O(nlog^2 n) ,很优美。 http://codeforces.com/blog/entry/49691 #include<c原创 2017-12-19 19:12:39 · 893 阅读 · 0 评论 -
[DP 倍增Floyd] LOJ#539.「LibreOJ NOIP Round #1」旅游路线
不算很难想。首先看到总钱数比较少,考虑 DPDP 出 fi,jf_{i,j} 表示从 ii 出发,已经在 ii 加了油,带了 jj 块钱,能走多远。 考虑如何转移,注意到油量比较大,所有不可能把它记到状态里。那我们就枚举下一次在哪里加油: fi,j=maxk{fk,j−pj+gi,k}f_{i,j}=\max_{k}\{ f_{k,j-p_j}+g_{i,k} \} 其中 gi,kg_{i原创 2017-11-05 16:00:07 · 582 阅读 · 0 评论 -
[背包 贪心] Codeforces #365D. Free Market
思维题。 首先要挖掘一下性质,这个交换的操作限制很大,较难处理。 可以发现,我们进行一次交换,价值总和增长不会超过 dd 。 若我们要从 SS 变到 TT,需用 S−S∩TS-S \cap T 交换得 T−S∩TT-S \cap T ,需满足 Sum(S−S∩T)+d≥Sum(T−S∩T)→Sum(S)+d≥Sum(T)Sum(S-S \cap T)+d \ge Sum(T-S \cap T原创 2017-11-03 22:13:11 · 473 阅读 · 0 评论 -
[补集转化 DP] ZROI 2017提高7 强军战歌
这题当时打的比较复杂的 DPDP,需要写 nn 棵有标记的线段树,复杂度是对的,但常数贼大…被卡成70… 实际上补集转化一下就变得很简单了。 先求出所有满足删完之后是个不降序列,但没有考虑之前是否已经不降的方案数。然后扣去不合法的。 我们可以 DPDP 求出 resires_i 表示长度为 ii 的不降子序列个数。就可以直接求答案了: ∑i=1nresi∗(n−i)!−∑i=2nresi∗i原创 2017-10-25 21:17:03 · 512 阅读 · 0 评论 -
[DP] Codeforces #626F. Group Projects
显然是 DPDP。这种贡献和最值有关的,一般用按顺序插入的方法 DPDP,会简单很多。有挺多类似的题的。 这题就是 fi,j,kf_{i,j,k} 表示插入了前 ii 个,有 jj 个块开发待插入,总代价为 kk。 每次插入 i+1i+1 就考虑是新开一个块还是插入原有块中,是否要闭合块。转移 O(1)O(1)。 有个问题就是一个块的贡献是延迟计算的,即闭合后才会确定贡献。kk 应该记什么呢?原创 2017-10-25 19:45:32 · 457 阅读 · 0 评论 -
[DP] Codeforces #623B. Array GCD
这题要找到一个突破点,不然难以下手。 注意到题面说不能全部删完,所以 a1,ana_1,a_n 至少有一个是不删去的。 这样就简单了,我们暴力得到 a1,a1+1,a1−1,an,an+1,an−1a_1,a_1+1,a_1-1,a_n,a_n+1,a_n-1 的质因数。共O(logV)O(\log V) 个。 然后枚举质因数,就可以 DPDP 了。fi,0/1/2f_{i,0/1/2} 表示原创 2017-10-25 18:02:54 · 475 阅读 · 0 评论 -
[贪心 + DP] Codeforces #571B. Minimization
不错的题。 容易想到按模 KK 分类 。每类的贡献时独立的,就是∑i|xi−xi+1|\sum_{i} |x_i-x_{i+1}| 这样的形式。如果我们已经确定了每类是哪些数,那么同类中排个序是最优的。 如何分配数分在哪一类呢 ? 发现我们一定是把连续的数放在一起比较优。 这样贪心的分析一下就变的很简单了,直接把 aa 数组排序。然后就是要把a分成 KK 段,每段的代价是末尾的值减去开头的值。原创 2017-10-25 14:46:20 · 319 阅读 · 0 评论 -
[DP] BZOJ4321. queue2
套路DP…这种和相邻数有关的一般考虑从小到大插入。 fi,j,0/1f_{i,j,0/1} 表示放了前 ii 个数,有 jj 个间隙两数相邻,0/10/1 表示 ii 和 i−1i-1 是否相邻。就好了。#include<cstdio>#include<algorithm>using namespace std;const int maxn=1005,MOD=7777777;typedef原创 2017-11-10 14:28:07 · 311 阅读 · 0 评论 -
[DP] BZOJ1801: [Ahoi2009]chess 中国象棋
大水题。显然限制就是同行同列个数不能超过2。fi,j,kf_{i,j,k} 表示前 ii 行,放了 00个的列数是 jj,放了 11 个的列数是 kk 。就好了…#include<cstdio>#include<algorithm>using namespace std;const int maxn=105,MOD=9999973;typedef long long LL;int n,m;原创 2017-11-01 14:29:59 · 310 阅读 · 0 评论 -
[DP] ZROI 2017提高 5 T2. 石头剪刀布
杜老师的好题。考虑一个暴力的 DPDP : f[i][p0][p1][p2]f[i][p0][p1][p2] 表示序列前 ii 个元素,分别以 0,1,20,1,2 为结尾的最长胜利子序列长度。简单的转移。这样复杂度是O(n4)O(n^4) 的,怎么优化呢?考虑到 p0,p1,p2p0,p1,p2 之间的差是很小的。因为可以在子序列头上删一两个得到以其他为结尾的子序列。在分析一下发现差不会超过 22原创 2017-10-07 20:56:36 · 450 阅读 · 0 评论 -
[DP] ZROI 2017 提高6 T2 异或统计
这题如果能知道一个答案的式子就很简单了,设 g[i][j]g[i][j] 表示取 ii 个数, 加和为 jj 的方案数。g数组直接 DPDP 出来就好了。则最终的答案就为: ∑i=1nim∑jg[K−j][n−i∗j]\sum_{i=1}^n i^m \sum_j g[K-j][n-i*j] 为什么是对的呢?注意到 g[K−j][n−i∗j]g[K-j][n-i*j] 的意义是至少取了 jj原创 2017-10-07 16:37:31 · 477 阅读 · 0 评论 -
[DP套DP] HDU5079: Square
题意给出一个n*n的网格,每个格子一开始都是黑的,且有些格子是损坏的。 现在可以任意选择一些非损坏格子染成白色。定义一个染色方案的优美度为白色最大子正方形的边长。 对于每个i=0~n,求优美度恰为i的染色方案。 n<=10题解显然是DP套DP。 首先思考最大子正方形这个全局的东西比较难用一个较简单的状态直接体现出来。 所以就分开来做,考虑容斥,如果我们求出了ans[i]表示最大子正方形边长原创 2017-06-28 21:38:43 · 890 阅读 · 2 评论 -
[期望DP+高斯消元] BZOJ3143: [Hnoi2013]游走
题意一个无向连通图,顶点从1编号到N,边从1编号到M。 小Z在该图上进行随机游走,初始时小Z在1号顶点。 每一步小Z以相等的概率随机选择从当前顶点出去的某条边走,并获得等于这条边的编号的分数。 当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。 n<=500题解直接算题目要求的东西有点难办。 首先边权的分配与小Z原创 2017-05-20 12:11:32 · 476 阅读 · 0 评论 -
[递推] 51nod 算法马拉松25 B. 完美序列
题意如果一个序列的相邻两项差的绝对值小于等于1,那么我们说这个序列是完美的。 给出一个有序数列A,求有多少种完美序列排序后和数列A相同。 n<=30000 每个数<=10^9,每个数出现次数<=100题解首先我们要想到从小到大考虑,不断的把数插入。 这样搞有什么好处呢?当要把i插入时,因为当前序列中所有数都比i小,所以i只能插到相邻两个i-1之间,或者边界有i-1的。 从这个角度,我们就能原创 2017-05-31 08:49:59 · 951 阅读 · 2 评论 -
[DP] BZOJ1831: [AHOI2008]逆序对
题意给出一个n个数的数列,每个数都是-1或是一个在1~K之间的数。-1表示这个位置可以填任意的数字。 求最少能有多少个逆序对。 (n<=10000 K<=100)题解bzoj双倍经验题 1831=1786 首先需要得到一个显然的结论,对于一个数列,如果我们交换一对逆序的元素,总逆序对数一点小于之前的总数。所以我们填的-1一定是不降的。 所以-1之间不会产生任何代价。 先O(n∗k∗log2原创 2017-04-25 09:42:08 · 510 阅读 · 0 评论 -
[DP] BZOJ4300: 绝世好题
题意给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足b(i) and b(i-1)!=0 (2<=i<=len)。题解绝世傻逼题。只是来水一发blog 设f[i]表示以i为结尾的最长长度,推的时候对于2进制每位,记一下在这位上有1的所有a[i]对应的f[i]的最大值即可。 复杂度O(n∗log2a[i])O(n*\log_2 a[i])#include<cstdio>#inclu原创 2017-05-05 16:22:26 · 467 阅读 · 0 评论 -
[AC自动机 + DP] BZOJ1030: [JSOI2007]文本生成器
题意给出n个单词。若一个字符串至少包含一个单词,就称这个字符串是”可读的”。 求长度为m的”可读的”字符串个数。所有字符都在[A,Z]范围。 n,m<=100题解首先一步转化,我们从补集考虑统计ans表示一个单词都不包含的串数,则答案为m26−ansm^{26}-ans。 多串匹配问题肯定要想到AC自动机。 我们要求的是长度为m的字符串没有匹配任何串的方案数。 长度对应AC自动机上走的次数原创 2017-05-01 20:10:40 · 498 阅读 · 0 评论 -
[置换群+背包] BZOJ1004: [HNOI2008]Cards
题意小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红,蓝,绿。 小春发明了M种不同的洗牌法,问Sun有多少种不同的染色方案。 两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种。 输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代 替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。 答案可能很原创 2017-04-09 19:43:02 · 459 阅读 · 0 评论 -
[DP+容斥] BZOJ1042: [HAOI2008]硬币购物
题意有4种硬币。面值分别为c1, c2, c3, c4。 Q组询问,每次给出4种硬币的使用个数上限di,以及一个数S,求组合出S的总面值的满足限制条件的方案数。 di,S<=100000, Q<=1000题解注意到硬币个数对于所有询问时固定的且个数很少,我们肯定需要预处理一些东西。 先不考虑硬币个数的限制,刷一次普通的背包得到f[i],表示用4种硬币组合出i的总面值的方案数。 显然对于每次询原创 2017-02-28 08:37:03 · 438 阅读 · 0 评论 -
[斜率优化DP] BZOJ1096: [ZJOI2007]仓库建设
题意有N个工厂按编号顺序排成一条直线,第1个工厂到第i个工厂的距离为dis[i], 第i个工厂一开始堆积着p[i]个货物,现在要紧急把所有货物装进仓库里。在第i个工厂建仓库需要c[i]的代价,对于没有建立仓库的工厂,其货物应被运往其他的仓库进行储藏,且只能往编号大仓库的运,一件货物运送1个单位距离的代价是1。求把所有货物装进仓库的最小代价。 (n<=100000)题解显然是DP,要用到斜率优化。原创 2017-02-12 11:03:54 · 677 阅读 · 0 评论 -
[DP] BZOJ1003: [ZJOI2006]物流运输
题意给出一个m个的无向图,你需要规划n天的运输方案。n天里,每天都要从S走到T走一次,每个点在某些天里不能经过。每天需要花费等于路径长度的代价,而且如果第i天选择的路径与第i-1天不同(i>1),还需要多花K的修改路线代价。求最小总代价。 (n<=100,m<=20)题解脑洞题,不算太难。可能一开始会想的比较远,如果考虑路径的变化,发现难以下手。实际上是个简单的线性DP。设f[i]表示前i天花费的原创 2017-02-11 21:58:19 · 445 阅读 · 0 评论 -
[DP套DP] UOJ#141. 【UER #4】量子态的棋盘
题意 n,m<=10 K<=1e+18题解这个小球数很大,但是注意到如果落在某个网格的小球数为偶数,必然是一半往上一半往下,与格子权值无关,只有当小球数为奇数的时候,最后一个小球的走向才和格子权值有关。 所以我们先推一趟,把不确定走向的小球留在那个位置。这样最多就只有n*m个球了。 然后考虑轮廓线DP,记下这里有几个小球从这个边界位置滚下。 这个状态数的数量比较玄学,反正就是能过的。 如何原创 2017-06-29 14:21:23 · 735 阅读 · 1 评论 -
[DP] BZOJ1025: [SCOI2009]游戏
题意windy学会了一种游戏。对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应。最开始windy把数字按 顺序1,2,3,……,N写一排在纸上。然后再在这一排下面写上它们对应的数字。然后又在新的一排下面写上它们 对应的数字。如此反复,直到序列再次变为1,2,3,……,N。 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 w原创 2017-07-11 09:07:41 · 382 阅读 · 0 评论