随笔分类 -  动态规划—dp

摘要:很像贪心的dp啊 这个定金尾款的设定让我想起了lolita和jk制服的尾款地狱…… 设f[i][j]为从j到i的付定金的最早月份然后从f[k][j 1]转移来,两种转移f[i][j]=min(f[i][j],f[j 1][k]+1)是当前这个月付[k 1,j 1]的尾款和[j,i]的定金,f[i][ 阅读全文
posted @ 2018-06-16 10:35 lokiii 阅读(112) 评论(0) 推荐(0)
摘要:A. Antipalindrome 还以为是什么神dp结果就是分情况讨论啊 原串是一串一样的字符的话输出0,是回文串的话输出n 1,否则直接输出原串长度 cpp include include using namespace std; const int N=200005; int n,d[N],s 阅读全文
posted @ 2018-06-02 14:22 lokiii 阅读(155) 评论(0) 推荐(0)
摘要:算是比较经典的高斯消元应用了 设f[i]为i点答案,那么dp转移为f[u]=Σf[v] (1 p/q)/d[v],意思是在u点爆炸可以从与u相连的v点转移过来 然后因为所有f都是未知数,高斯消元即可(记得输出大难的时候除以总概率和) cpp include include using namespa 阅读全文
posted @ 2018-05-25 17:09 lokiii 阅读(157) 评论(0) 推荐(0)
摘要:其实是可以斜率优化的但是没啥必要 设st为花费时间的前缀和,sf为Fi的前缀和,f[i]为分组到i的最小花费 然后枚举j转移,考虑每次转移都是把j到i分为一组这样意味着j及之后的都要增加s的时间,同时增加这段的结束时间/ F,取min即可 cpp include include using name 阅读全文
posted @ 2018-05-25 14:45 lokiii 阅读(282) 评论(0) 推荐(0)
摘要:满脑子组合数学,根本没想到dp 设f[i][j]为前i只蚂蚁,选出j只的方案数,初始状态为f[0][0]=1 转移为 $$ f[i][j]=\sum_{k=0}^{a[i]}f[i 1][j k] $$ $$ f[i][j]=\sum_{k=max(j a[i],0)}^{j}f[i 1][k] $ 阅读全文
posted @ 2018-05-09 17:26 lokiii 阅读(112) 评论(0) 推荐(0)
摘要:把长度转成右端点,按右端点排升序,f[i]=max(f[j]&&r[j] include include using namespace std; const int N=100005; int n,t[N],f[N],ans; struct qwe { int l,r; }a[N]; bool c 阅读全文
posted @ 2018-05-08 21:26 lokiii 阅读(125) 评论(0) 推荐(0)
摘要:DAG上的dp 因为本身升序就是拓扑序,所以建出图来直接从1到ndp即可,设f[i][j]为到i花费了j cpp include include using namespace std; const int N=1005,inf=1e9+7; int n,m,b,h[N],cnt,f[N][N],a 阅读全文
posted @ 2018-05-07 14:45 lokiii 阅读(125) 评论(0) 推荐(0)
摘要:预处理出g[i][j]表示原串第i个匹配第j个单词需要去掉几个字母(匹配不上为 1) 设f[i]为i及之后满足条件要去掉的最少字母 倒着dp! f[i]初始为f[i+1]+1,转移方程为f[i]=min(f[i],f[i+strlen(b[j]+1)+g[i][j]]+g[i][j]) 也不是很难理 阅读全文
posted @ 2018-05-06 22:02 lokiii 阅读(167) 评论(0) 推荐(0)
摘要:设f[i]为i时刻最小花费 把牛按l升序排列,每头牛能用f[l[i] 1]+c[i]更新(l[i],r[i])的区间min,所以用线段树维护f,用排完序的每头牛来更新,最后查询E点即可 cpp include include include using namespace std; const in 阅读全文
posted @ 2018-05-05 20:43 lokiii 阅读(186) 评论(0) 推荐(0)
摘要:参考:http://hzwer.com/3917.html 好神啊 注意到如果分成n段,那么答案为n,所以每一段最大值为\\( \sqrt{n} \\) 先把相邻并且值相等的弃掉 设f[i]为到i的最小答案,b[j]表示的是从b[j]+1开始到i共有j个不同的数字,p[a[i]]表示a[i]上次出现 阅读全文
posted @ 2018-05-05 18:03 lokiii 阅读(228) 评论(0) 推荐(0)
摘要:参考:https://www.cnblogs.com/N C Derek/archive/2012/07/11/usaco_09_open_tower.html 虽然长得很像斜率优化,但是应该不算…… 贪心是错的,对拍出好多异常情况 s[i]为前缀和,从顶向下dp;设f[i]为本层宽度,g[i]为这 阅读全文
posted @ 2018-05-05 10:39 lokiii 阅读(123) 评论(0) 推荐(0)
摘要:参考:https://blog.csdn.net/cgh_andy/article/details/52506738 没有get到什么重点的dp……做的莫名其妙 注意滑雪一个坡可以滑很多次 设f[i][j]为时间为i能力为j的最大滑雪次数,预处理l[i][j]为在i时获得j能力的最晚开始时间,w[i 阅读全文
posted @ 2018-05-04 08:27 lokiii 阅读(170) 评论(0) 推荐(0)
摘要:这不就是个n方dp吗……看了眼洛谷题解简直神仙打架 我全程没用到n…… 把休息时间并入产奶时间,注意“结束时间不挤奶”,所以ei=ei+r 1,注意这个 1! 然后按r排序,设f[i]为选i的最大收益,因为r是单调的所以直接从左到右扫一遍满足rj include include using name 阅读全文
posted @ 2018-05-03 21:15 lokiii 阅读(180) 评论(0) 推荐(0)
摘要:因为是单调不降或单调不升,所以所有的bi如果都是ai中出现过的一定不会变差 以递增为例,设f[i][j]为第j段选第i大的高度,预处理出s[i][j]表示选第i大的时,前j个 a与第i大的值的差的绝对值 的和。 转移显然是 $$ f[i][j]=min{f[i 1][k]+s[i][j] s[i][ 阅读全文
posted @ 2018-05-03 10:11 lokiii 阅读(103) 评论(0) 推荐(0)
摘要:设f[i]为i的方案数,f[1]=1,考虑转移,如果是奇数,那么就是f[i]=f[i 1]因为这1一定要加;否则f[i]=f[i 1]+f[i 1],就是上一位+1或者i/2位所有因子乘二 阅读全文
posted @ 2018-04-30 19:10 lokiii 阅读(107) 评论(0) 推荐(0)
摘要:最长上升子序列。虽然数据可以直接n方但是另写了个nlogn的 转移:f[i]=max(f[j]+1)(a[j] include using namespace std; const int N=5005; int n,a[N],f[N],ans; int read() { int r=0,f=1; 阅读全文
posted @ 2018-04-27 21:26 lokiii 阅读(236) 评论(0) 推荐(0)
摘要:写了个bfs发现MLE了... 设f[t][i][j]为在t时刻走到(i,j)的方案数,转移和bfs一样 cpp include include using namespace std; const int N=105,dx[]={1, 1,0,0},dy[]={0,0, 1,1}; int n,m 阅读全文
posted @ 2018-04-27 14:06 lokiii 阅读(117) 评论(0) 推荐(0)
摘要:不知道算不算博弈 很妙的贪心,一直在想SG函数结果... 首先从大到小排个序,然后考虑当前的人要怎么选:如果不选最后一段,那么另一人会选,这样不利于当前的人,所以每个人一定会选最后一段 设f[i]为要选i了,先手的最大差,显然是max(a[i] f[i 1],f[i 1]),就是先手只选了最后一个和 阅读全文
posted @ 2018-04-26 17:58 lokiii 阅读(144) 评论(0) 推荐(0)
摘要:首先处理处理出来哪些边能连——能把羊分成两个偶数部分的,实现是在凸包上枚举极点,极角排序,枚举凸包上点对判断两边羊的个数的奇偶即可,设可以连边为v[i][j]=1 然后设f[i][j]为从i到j个凸包上点的方案数,初始状态是相邻点f[i][i+1]=1,转移是 $$ f[i][j]=\sum_{k= 阅读全文
posted @ 2018-04-26 09:26 lokiii 阅读(260) 评论(0) 推荐(0)
摘要:要求三边和大于第四边,所以任意一条边的长度都是小于n/2 设f[i][j]为前i条长为j,转移的时候用n/2限制 cpp include include using namespace std; int n,mx,f[5][2505]; int main() { f[0][0]=1; scanf(" 阅读全文
posted @ 2018-04-25 09:37 lokiii 阅读(137) 评论(0) 推荐(0)