dp
jinxes6
这个作者很懒,什么都没留下…
展开
-
AtCoder Beginner Contest 215 E - Chain Contestant
AtCoder Beginner Contest 215 E - Chain Contestant给出一个只包括A~J的字符串,定义一种子序列为:在这个子序列中,相同的字符必定连续出现,求出这样的子序列有多少个。数据范围:字符串长度1 <= n <= 1000看起来就是一道状压dp,但是写得不是很顺利,所以在这里回顾一下。定义dpi,j,kdp_{i,j,k}dpi,j,k为,到字符串的第i位,出现过j种类的字符(j是状态压缩),目前最后的一位为k。状态转移的时候,我们可以认为当原创 2021-08-22 14:03:40 · 166 阅读 · 0 评论 -
AtCoder Beginner Contest 204 F Hanjo 2
AtCoder Beginner Contest 204H宽,W长的二维平面上,用1 * 1或者2 * 1的地砖来铺,要求铺满,求出方案数。数据范围H <= 6, W <= 1e12看到W的范围就可以想到是一个矩阵快速幂优化的dp转移,问题的关键是如何写出dp的方程以及矩阵的构造。这里题解的巧妙在于状态的定义,因为不好处理1 * 2的地砖横着摆的情况,因为这会跨两行,我开始以为会有2^12,也就是枚举两行的状态。不过这里状态的定义是当前行的二进制状态压缩,并且要保证前一行是已经塞满的原创 2021-07-31 00:03:00 · 338 阅读 · 1 评论 -
luogu p3515 Lightning Conductor
luogu p3515 Lightning Conductor给定一个长度为n的序列,对于每一个i∈[1,n]i∈[1,n]i∈[1,n],求出一个最小的非负整数p,使得对于所有的j∈[1,n]j∈[1,n]j∈[1,n],都有aj<=ai+p−∣i−j∣a_j<=a_i+p-\sqrt{|i-j|}aj<=ai+p−∣i−j∣通过这个题学习到两点,一个是用分治的方法解决1D1D类型的四边形优化dp问题,另一个是根据凸性来得到四边形不等式。稍微对于原来的式子做一点变化,可以原创 2021-07-18 13:32:16 · 52 阅读 · 0 评论 -
Yinchuan-B The Great Wall
yinchuan-B The Great Wall给出n个数,将其划分为k个区间,要求每个区间当中的最大数和最小数的差值之和最大。求k从1到n的答案。n <= 1e4因为这个题开始学四边形优化,其实会了之和回头看感觉还是蛮简单的,w(i,j)w(i,j)w(i,j)的四边形不等式很好证明,然后用个ST表来实现O(1)O(1)O(1)的查询,1e8的空间还是有点大,所以学着写了滚动数组。这个代码是按照印象中的题意随便糊的,就过了一下样例,没有在oj上进行测试。const int N = 1原创 2021-07-18 13:29:20 · 145 阅读 · 0 评论 -
codeforces round721 div2. E
给n(n<=35000)个数,要求分成k(k<=100)个区间。每个区间当中如果有多个相同的数,那么答案就会加上这个数最后一个减去最前一个的位置。要求划分后答案最小的值是多少。最近四边形优化做的有点多,下意识觉得可以用决策单调性,但是想想好像不太能够存的下(可能要用一些比较高级的数据结构),看了其他人的代码,发现都是用的线段树。首先写出dp方程:,然后我们考虑a[j]对于答案的贡献,假设a[j]上一次出现的位置是pre[j]:1.a[j]在区间(pre[j]+1...原创 2021-07-18 13:24:48 · 60 阅读 · 0 评论 -
luogu p4767 邮局
给定V个村庄的位置xi,建P个邮局,使每个村庄到最近的邮局的距离之和最小。P<=300,P<=V<=3000,1<=xi<=10000这是个类2D1D的dp,状态由转移得到,依次推出以下结论:时,并且从而得到从而有决策单调性最后,当我们需要求出的时候,只需要枚举作为决策区间即可。注意到需要的值,所以需要倒着枚举。const int N = 3010, M = 310, inf = 1e9;int a[N], w[...原创 2021-07-18 13:19:03 · 144 阅读 · 0 评论 -
51nod 1022 石子合并v2
就是石子合并的数据范围变为了1e3经典四边形优化区间dpconst int N = 2e3 + 10;const long long inf = 1e18;long long dp[N][N], sum[N];int m[N][N], a[N];int main(){ int T = 1; //T = read(); while (T --) { int n; n = read(); for (int i = 1; i <= 2 * n; i ++) ..原创 2021-07-18 13:08:12 · 68 阅读 · 0 评论