一些前言:

据说动态规划会用排序,数据结构来进行乱搞优化操作

动态规划滴核心是个啥呢?状态表示和状态转移

设状态:哪些因素会影响到最终答案,就把哪些因素用数组的维度表示出来

要充分描述,也要简洁

举个例子

计算从(1,1)走到(x,y)的方案数:

走到任意一个(p,q),只能从(p-1,q)和(p,q-1)走过来

那dp[x][y]=dp[x-1][y]+dp[x][y-1]

例一:

最长上升子序列

这个比较简单

dp[i]表示以a[i]为结尾的最长上升子序列的长度

dp[i]=max{dp[j]}+1(a[j]<a[i]&&j<i)

复杂度O(n2)

更秀一点的O(nlogn)做法:

len记录当前的最长上升子序列的长度,d[i]记录当前找到的最长上升子序列的第i项,若a[now]≤d[len],则找到第一个d[j]>a[now]的j,令d[j]=a[now],否则len++,d[len]=a[now],最后的len是最终答案,但d数组不一定是真正的最长上升子序列

dp[i][j]表示前i个位置用j个乘号的最大值

cnt(i,j)表示原数字串第i个数字到第j个数字所组成的数

dp[i][j]=max(dp[i][j],dp[k][j-1]*cnt(k+1,i))

挂饰:

看起来像个贪心(大雾)

那就排个序

按照Ai从大到小排

why?

因为挂钩越多,能挂的东西就越多

dp[i][j]=max(dp[i-1][j],dp[i-1][max(j-a[i],0)+1]+b[i])

蓝字部分是挂第i个挂钩的喜悦值

看蓝字部分的第二维,为什么+1要写在外面呢?

①:当j-a[i]+1<0时,j-a[i]肯定小于0,这时候考虑j-a[i]+1的状态是没有意义的,直接考虑手机上只有一个挂钩的情况

②:当j-a[i]+1==0时,那说明挂上i,就没有挂钩了,并且挂i只需要一个挂钩,也就是说之前手机上只有一个挂钩。如果我们写成max(j-a[i]+1,0),此时是转移到之前手机上没有挂钩的状态,是不对滴。

综上,+1要写在外面

最终答案:max{dp[n][i]}(0≤i≤n)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
inline int read()
{
char ch=getchar();
int x=;bool f=;
while(ch<''||ch>'')
{
if(ch=='-')f=;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return f?-x:x;
}
int n,dp[][];
struct G{
int a,b;
}g[];
bool cmp(G x,G y)
{
return x.a>y.a;
}
int main()
{
n=read();
for(int i=;i<=n;i++)
g[i].a=read(),g[i].b=read();
sort(g+,g++n,cmp);
memset(dp,0xcf,sizeof(dp));
dp[][]=;dp[][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
dp[i][j]=max(dp[i-][j],dp[i-][max(j-g[i].a,)+]+g[i].b);
}
}
int ans=0xcfcfcfcf;
for(int i=;i<=n;i++)
ans=max(ans,dp[n][i]);
printf("%d",ans);
}

代码

(手机好沉ρωρ)

洛谷P1233 木棍加工

看起来像求最长不上升子序列个数,但是这似乎是二维的

那我们按照l从大到小排序,再看w中有多少个不上升子序列的最少的数量

那怎么求最少的不上升子序列的数量?

dilworth定理(翻译成人话版本):

最少的不上升子序列的数量就是最长上升子序列的长度(似乎在导弹拦截里面见过)

why?

度娘大概知道

P1091合唱队形

nlogn做法qwq(导弹拦截的做法)

辣么另一种是什么呢?

我们回顾求最长上升子序列的时候,我们要找最大的dp[j],使得a[j]<a[i]

我们换个角度

就是找最大的k,使得dp[j]==k&&j<i&&a[j]<a[i]

很有可能有多个dp[j]==k

我们设置辅助数组h,h[k]为dp[j]==k中,最小的a[j]

同时h数组是单调递增的,所以查询时只要查询最大的小于a[i]的h数组的下标即可(二分查找)

为什么是单调递增的?

数据结构优化

暴力的不要不要的

据说是个二维偏序

用树状数组搞

维护前缀最大值

如果要求公共子序列的个数怎么办

dp[i][j]:第一个串的前i个字母,第二个串的前j个字母的公共子序列的个数

若s[i]==t[j],选:转移到dp[i-1][j-1],不选:dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]  (这一块是重复的)

若不相等:dp[i-1][j]+dp[i][j-1]

数据范围你猜

好吧是复杂度是n2

先来个n4的暴力

dp[i][j]:A的前i,B的前j的balabala

然后搞一遍公共子序列的dp转移,如果小于末尾的数,就再找一遍

唉唉这为毛是四维的??

在算dp[i][j]时要看dp[1][1],dp[1][2]...dp[1][j-1],dp[2][1]...一直到dp[i-1][j-1]

这样就是n2

但是还是可以nb的继续优化

我们再设f[j]=max{dp[x][j]}(1<=x<=i-1)

当i到i+1的时候,只需要O(1)更改f[j]就可以了

这样总体就是O(n2)了

代码:

a[i]>b[j]是个什么鬼咧?

结合一下这张图。我们保证当前子序列的结尾是a[i],如果我们要更新后面的dp[i][j'],就是要求b[j']要小于a[i](当然,b[j]也要小于a[i])

tmp又是个啥?

tmp就是

红色圈里这一坨的最大值

好像似乎也许应该可能是一样的叭

dp and 容斥

zhx说小学学过(手动双关)

什么是容斥?加加减减乱搞一通

注意这里的n和m是10^8

算了我们简化一下10^6

肯定裸dp是药丸的

辣么我们用数学解决

容斥原理qwq

总路径-至少经过一个点+至少经过两个点-至少经过三个点+至少经过4个点.........

我们可以dp出容斥系数

奇数就减,偶数就加

复杂度O(t2)

窝莫得听懂

来我们看看记忆化搜索

终于有一道数据范围人类的题了

如果我们只有一个dfs(x,y)表示从(x,y)走到(n,m)的距离

我们再dfs中可能多次调用同一个dfs(i,j),这样我们就可以把dfs(i,j)记下来,这就是记忆化搜索

做题步骤(雾

似乎搜索可以

哎参数不多唉

有的值重复计算了???

那就记下来

遇见duliu搜索顺序题怎么办

记忆化!!!(据说记忆化还有剪枝效果)

bzoj 3810

这是个好题

我们发现合法的一定有一条贯穿整个矩形的线

那我们就枚举贯穿线,算出左边差异度,右边差异度的最小值

设dp[i][j][4]为长为i,宽为j的矩形面对大海春暖花开状态

就是把一个矩形切成一堆小矩形

拓扑图dp

什么意思?

就是求从一个入度为0的点到达一个出度为0的点的方案数

dp[i]=∑dp[j](存在j到i的边)

我们可以边跑拓扑序,边计算dp[i]

最后出度为0的点的dp值的和就是答案

最短路图怎么建?

如果dis[u]+len[edge[i]]=dis[v],那么edge[i]就在最短路径上

然后求到T的方案数

最大子矩阵

n4乱搞

其实如果数据保证都是正整数,那就是O(n2)的

正解:先对行进行组合,选取组合中的行,把每一列上的数加起来,就变成了一行数,然后求最大子段和

所有组合中最大子段和的最大值就是答案

举个例子叭

1 2 -10 6

2 -1 3 7

3 -5 9 8

这个矩阵一共有3行

那么行的组合有{(1),(2),(3),(1,2),(1,3),(2,3),(1,2,3)}

先对行1进行合并(其实不用合并),得到1 2 -10 6,跑最大子段和

行2和行3的省略辣(反正只有一行也没有什么可以合并的)

接下来才是真正的合并

取1,2行

1 2 -10 6

2 -1 3 7

同一列上的数字相加:

第一列:1+2=3

第二列:2-1=1

第三列:-10+3=-7

第四列:6+7=13

这样得到新的一行数: 3 1 -7 13,跑最大子段和

然后是对(1,3)(2,3)(1,2,3)这样搞,求出来所有的最大子段和中最大的那个就是答案

序列上设计dp

bzoj1003

f[i]表示前i天的最小中成本

可以套这个:

跑最短路,注意此处的最短路要保证在所有天里,起点和终点都可以互达

f[i]=min{f[j]+jl[j+1][i]*(i-j)+k}

bzoj1296

考虑只有一条木板

f[i][j]:刷到第i个格子,用了j次,最多正确粉刷的格子数

f[i][j]=max{f[k][j-1]+cnt(j+1,i)}(枚举k)

cnt:可以搞个前缀和,然后计算[j+1,i]中红色格子的数量,蓝色格子的数量,取max

再考虑有好多条木板

g[i][l]表示前i个木板一共刷了l次,最多的数量

g[i][l]=max{g[i-1][l-x]+fi[m][x]|x≤m}

什么意思呢?枚举木板i粉刷的次数,找最大值

设左括号为+1,右括号为-1

则总和为0,任意前缀和≥0

dp[i][j]前i个位置的前缀和为j的方案数

我们发现括号序列中的某些部分可以左右括号抵消

就像这样:(()))) ---------------> ))

回想一下打怪那个题

对于回血怪(a[i]-d[i]>0),我们按照d[i]升序排序,对于扣血怪(a[i]-d[i]<0),我们按照a[i]降序排序

和这个题联系一下

我们把左括号当做+1,右括号当做-1,先进行化简(左右括号互相抵消)。化简完的序列的右括号一定在左括号的左边,数量用L[i]表示。左括号的数量用R[i]表示,要选出尽可能多的括号序列,也就是要打尽可能多的怪,就按照打怪的方法排序

f[i][j]表示前i个序列,+1,-1和为j时的最长长度,len[i]是排完序后第i个括号序列的最初长度

f[i][j]=max(f[i-1][j-L[i]+R[i]]+len[j],f[i-1][j])

ans=f[n][0]

一套有趣的题

卡特兰数???(不是记搜吗(っ°Д°;)っ)

对f[n]来说,第一个左括号一定有一个与之匹配的第一个右括号,那就枚举它们中间有多少对括号。若有i对,则贡献是f[i]*f[n-1-i]

f[n]=∑f[i]*f[n-1-i](0≤i≤n-1)

上面就是卡特兰数的公式辣

其他的卡特兰数的问法:

证明:

3:左右子树不一样,设左子数的大小为i,右子树的大小就是n-i-1,乘一乘还是原来的公式

4:这里其实是求的n+2条边的凸多边形

5:把往右走当做+1,往上走当做-1,保证前缀和为0,最后和为0,还是括号匹配问题

贪心的选取每个区间的最小值

这就是那个滑块的题辣

辣么怎么用单调队列优化这个题呢?

队头维护最小值,如果最小值的下标小于当前区间的左端点就pop掉,每次插入,如果前面的值比当前插入的值大,就pop掉,这样队头一直是当前区间的最小值辣

利用辅助数组优化

.....举个例子

dp[i][0][0]--------------->dp[i+1][1][1],且第一个串是ab?:

dp[i+1][1][1]=dp[i][0][0]*f[a][b][?][0][0][1][1]

说人话:f数组处理16种转移的系数

为毛是16种?

例一:合并石子

ρωρ

poj3280

dp[l][r]表示[l,r]变为回文串的最小值

如果s[i]≠s[j],考虑[i,j-1]和[i+1,j](删掉s[i]或s[j])

dp[i][j]=min(dp[i+1][j]+add[s[i]],dp[i+1][j]+del[s[i]],dp[i][j-1]+add[s[j]],dp[i][j-1]+del[s[j]])

若s[i]==s[j],则dp[i][j]=dp[i+1][j-1]

括号最大匹配

dp[i][j]表示[i,j]内最长的合法子序列

考虑当前的括号是否匹配

没匹配:dp[i][j]=dp[i+1][j]

匹配:枚举和谁匹配

若i和k匹配,则dp[i+1][k-1]是合法的,dp[k+1][j]还要选出一个合法的子序列

所以dp[i][j]=max{dp[i+1][k-1]+dp[k+1][j]}

为毛上一个题不枚举和谁匹配呢?明明好像都是回文串的亚子

因为上一个题只能是回文串,但这个题可以是多个回文串拼起来

n≤100:枚举断点

n显然超过O(n3)允许的数据:一般来说是只考虑边界情况,不枚举断点

bzoj1900

dp[i][j]:折叠区间[i,j]的最小代价

我们可以枚举断点唉

一个折叠的区间可能由两个区间拼接而成,就枚举断点

①:自身可以压缩:找循环节的长度k(hash),dp[i][j]=dp[l][k]+2+区间长度/(k-l)+1

②:由可以压缩的子区间拼接而成,dp[i][j]=min{dp[i][k]+dp[k+1][j]}

环形问题

就是把一个环,断开成链,然后再把原来的链复制一遍接到后面

能量项链

如果它是个链:dp[i][j]=max{dp[i][k]+dp[k+1][j]+h[i]*h[k]*t[j]}

但是环可以搞出dp[4][3]这种操作,所以....

要环变链

dp[i][j]=min{dp[i][k]+dp[k+1][j]+gcd(a[i],a[j])}

似乎好像真的没什么东西

dp基础大概 (8.6)的更多相关文章

  1. 【专章】dp基础

    知识储备:dp入门. 好了,完成了dp入门,我们可以做一些稍微不是那么裸的题了. ----------------------------------------------------------- ...

  2. 【学习笔记】dp基础

    知识储备:dp入门. 好了,完成了dp入门,我们可以做一些稍微不是那么裸的题了. dp基础,主要是做题,只有练习才能彻底掌握. 洛谷P1417 烹调方案 分析:由于时间的先后会对结果有影响,所以c[i ...

  3. hdu 2089 不要62 (数位dp基础题)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. poj 2955 Brackets (区间dp基础题)

    We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a ...

  5. DP基础(线性DP)总结

    DP基础(线性DP)总结 前言:虽然确实有点基础......但凡事得脚踏实地地做,基础不牢,地动山摇,,,嗯! LIS(最长上升子序列) dp方程:dp[i]=max{dp[j]+1,a[j]< ...

  6. 树形dp基础

    今天来给大家讲一下数形dp基础 树形dp常与树上问题(lca.直径.重心)结合起来 而这里只讲最最基础的树上dp 1.选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程 ...

  7. poj2642 The Brick Stops Here(DP基础题)

    比基础的多一点东西的背包问题. 链接:POJ2642 大意:有N种砖,每种花费p[i],含铜量c[i],现需要用M种不同的砖融成含铜量在Cmin到Cmax之间(可等于)的砖,即这M种砖的含铜量平均值在 ...

  8. UVA103 dp基础题,DAG模型

    1.UVA103 嵌套n维空间 DAG模型记忆化搜索,或者 最长上升子序列. 2.dp[i]=max( dp[j]+1),(第i个小于第j个) (1) //DAG模型记忆化搜索 #include< ...

  9. hdu 1561 The more, The Better(树形dp,基础)

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. ubuntu14 文件夹添加/删除书签

    1. 打开文件管理,进入你要添加书签的目录 2. 把鼠标移到顶部选择“Bookmarks" 3. 这是文件管理左侧可以看到 4. 右键可以选择删除

  2. Tomcat域名与服务器多对多配置

    参考: https://www.cnblogs.com/yueshutong/p/9381566.html

  3. 小白学Python——Matplotlib 学习(1)

    众所周知,通过数据绘图,我们可以将枯燥的数字转换成容易被人们接受的图表,从而让人留下更加深刻的印象.而大多数编程语言都有自己的绘图工具,matplotlib就是基于Python的绘图工具包,使用它我们 ...

  4. 好用的 Puppeteer 辅助工具 Puppeteer Recorder

    Puppeteer Puppeteer 是一个Node库,它提供了一个高级API来控制DevTools协议上的Chrome或Chromium,常用于爬虫.自动化测试等,你在浏览器手动完成的大多数事情都 ...

  5. Restful风格API中用put还是post做新增操作有什么区别?

    Restful风格API中用put还是post做新增操作有什么区别? 转 头条面试归来,有些话想和Java开发者说!>>> 这个是华为面试官问我的问题,回来我找了很多资料,想验证这个 ...

  6. PCIeの数据链路层与物理层详解

    数据链路层(DLL,Data Link Layer)的主要作用是进行链路管理(Link Management).TLP错误校验.Flow Control(流控制)和Link功耗管理.不仅可以接收发送来 ...

  7. Python 通过RSA实现license验证设备指纹与有效期

    前言 本文使用RSA非对称加密算法,了解详情请访问: RSA 非对称加密算法简述 https://blog.csdn.net/ctwy291314/article/details/88821838 P ...

  8. 基于maven搭建hibernate运行环境

    准备案例需要的数据库表和测试数据 建表语句: create table DEPARTMENT ( DEPT_ID integer not null, DEPT_NAME ) not null, DEP ...

  9. Qt Creator的初步使用

    http://c.biancheng.net/view/1804.html 启动 Qt Creator,出现如图 1 所示的主窗口: 图 1 Qt Creator主窗口 Qt Creator 的界面很 ...

  10. Jmeter--逻辑控制之if控制器(转)

    一.背景 在实际工作中,当使用Jmeter做性能脚本或者接口脚本时,有可能会遇到需要对不同的条件做不同的操作,基于这种诉求,在Jmeter中可使用if控制器来实现 二.实际操作 逻辑控制器位置: 在线 ...