随笔分类 -  动态规划

摘要:dp常识 增加状态可以消除后效性 举个例子 在有环图上跑dp,有后效性,但是多加1位,第i步在第j点便可以消除后效性 阅读全文
posted @ 2020-11-15 22:44 WeiAR 阅读(190) 评论(0) 推荐(0) 编辑
摘要:Problem F – Fabricating Sculptures https://codeforces.com/gym/102428/problem/F 这是一个按层决策的dp,即它只能有一个极值而且是最大值,我当时是想的按列处理,结果卡住了但是如果按行从下往上来看,它就是单调不增的f[i][j 阅读全文
posted @ 2020-10-13 17:35 WeiAR 阅读(162) 评论(0) 推荐(0) 编辑
摘要:K. Pope's work http://codeforces.com/gym/298615/problem/K f[i][j]表示前面i个箱子,堆了j个高度所需要的最小重量先按承重排序,最优答案是承重从下往上依次不增的 转移就很简单了,如果当前这个能够承担之前的j-1个箱子,就把它放在最下面。 阅读全文
posted @ 2020-10-13 15:19 WeiAR 阅读(180) 评论(0) 推荐(0) 编辑
摘要:SOS DP/Gym - 102576B 我看懂了!!契机:排位赛B题,愣是不会求,😭Sum over subsets -> SOS比如这样一个问题:给你一个长度为n的数组,然后统计有多少个数对 (a[i]&a[j])==a[i];把a[j]化为2进制 100010101, 那也就是找出满足 a[ 阅读全文
posted @ 2020-09-28 13:07 WeiAR 阅读(184) 评论(0) 推荐(0) 编辑
摘要:f[i][j]表示向上扩展了i行,向右扩展了j列的方案数显然f[i][j]=f[i-1][j]*j+f[i][j-1]*i;但是这样会有重复的怎么去重是关键,top行和right列对称操作会重复算,所以最后为f[i][j]=f[i-1][j]*j+f[i][j-1]*i-(i-1)*(j-1)*f[ 阅读全文
posted @ 2020-07-22 10:39 WeiAR 阅读(247) 评论(0) 推荐(0) 编辑
摘要:每个位置的数变化最多为[0,1,2],就像1,1,2这种情况,中间位置最多加2,我们从后往前处理 #include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) #defi 阅读全文
posted @ 2020-07-22 10:34 WeiAR 阅读(145) 评论(0) 推荐(0) 编辑
摘要:#include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) //by wa 阅读全文
posted @ 2020-07-15 13:00 WeiAR 阅读(1486) 评论(0) 推荐(0) 编辑
摘要:自己独立做出来的第一道数位dp(虽然一共做了3道qwq #include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(lon 阅读全文
posted @ 2020-07-14 11:24 WeiAR 阅读(122) 评论(0) 推荐(0) 编辑
摘要:数位dp模板题 #include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(int i=a;i<=b;++i) //by 阅读全文
posted @ 2020-07-13 10:52 WeiAR 阅读(138) 评论(0) 推荐(0) 编辑
摘要:https://vjudge.net/contest/376754#problem/C 一个不错的区间dp,可惜我当时看错题了,忘记了得是二叉搜索树,按普通树来做的,就60分。 f[i][j]表示区间[i,j]合法 l[i][k]表示[i,k-1]能构成k的左子树 r[k][j]表示[k+1,j]能 阅读全文
posted @ 2020-06-06 14:20 WeiAR 阅读(160) 评论(0) 推荐(0) 编辑
摘要:https://vjudge.net/contest/372814#problem/E n=15考虑状压dp #include <bits/stdc++.h> #define inf 2333333333333333 #define N 1000010 #define p(a) putchar(a) 阅读全文
posted @ 2020-05-12 19:00 WeiAR 阅读(849) 评论(0) 推荐(0) 编辑
摘要:https://vjudge.net/contest/365698#problem/J l[i]表示以a[i]为右端点的为负数的情况,r[i]表示为整数。 转移就是这样: if(a[i]<0){ l[i]=r[i-1]+1; r[i]=l[i-1]; } else{ l[i]=l[i-1]; r[i 阅读全文
posted @ 2020-04-03 20:01 WeiAR 阅读(137) 评论(0) 推荐(0) 编辑
摘要:超妙的树形dp一个递归,一个递推f[i]表示i结点往下走的最远距离,g[i]表示往上走的最远距离f[i]=max(f[j])+i->v;g[i]=max(g[pa],f[e[pa]->n]+e[pa]->v)+i->v; #include <iostream> #include <cstdio> # 阅读全文
posted @ 2020-03-27 22:08 WeiAR 阅读(494) 评论(0) 推荐(0) 编辑
摘要:二分答案出最小距离,dpcheck,单调队列优化dp #include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 阅读全文
posted @ 2020-03-19 19:34 WeiAR 阅读(169) 评论(0) 推荐(0) 编辑
摘要:是一个单调队列优化dp的典型例子。f[i]=min(f[j])+1,从[i-k,i-1]中转移过来,维护单调递增的队列,每次取队首元素+1就好了。转移分两种情况,[0,i]或者[i-k,i]这个区间里全是01交替的,那么你只能选f[i-1]也就是最大的,取队尾元素就可以了;否则取队首。 #inclu 阅读全文
posted @ 2020-03-11 21:33 WeiAR 阅读(103) 评论(0) 推荐(0) 编辑
摘要:http://47.95.147.191/contest/4/problem/Af[i][j]表示已经完成j道且最后一个月完成[i,j]题目的最少月数。 #include <iostream> #include <cstdio> #include <queue> #include <algorith 阅读全文
posted @ 2020-02-25 22:15 WeiAR 阅读(192) 评论(0) 推荐(0) 编辑
摘要:CodeForces - 981D 从高位到低位去枚举,如果存在一种分配>=(ans|i),ans|=i;检验的时候用区间dp,f[i][j]表示前i个分成j段能不能成功,当然每一段都>=(ans|i) #include <iostream> #include <cstdio> #include < 阅读全文
posted @ 2020-02-22 20:17 WeiAR 阅读(134) 评论(0) 推荐(0) 编辑
摘要:严格上升的话,减1就好啦 阅读全文
posted @ 2019-07-30 09:59 WeiAR 阅读(127) 评论(0) 推荐(0) 编辑
摘要:Gym - 100543Lhttps://vjudge.net/problem/153854/origin区间dp,要从区间长度为1开始dp 阅读全文
posted @ 2019-07-20 20:05 WeiAR 阅读(141) 评论(0) 推荐(0) 编辑
摘要:https://vjudge.net/problem/2198220/origin枚举等差数列第一个和第二个,然后二分确定数列后面是否存在,复杂度比较玄学,卡过了。 也可以dp做,f[j][i]=max(f[j][i],f[i][pre]+1);f[j][i]表示j是等差数列最后一个下标,i是倒数第 阅读全文
posted @ 2019-07-16 20:16 WeiAR 阅读(911) 评论(0) 推荐(0) 编辑