dp常见优化方法
noip范围内的dp优化方法:
加速状态转移
1.前缀和优化
2.单调队列优化
3.线段树或树状数组优化
精简状态
3:精简状态往往是通过对题目本身性质的分析,去省掉一些冗余的状态。相对以上三条套路性更少,对分析能力的要求更高。
前缀和优化
逆序对(loj)
求长度为n,逆序对为k的排列有多少个,答案对10^9^+7取模
1<=n,k<=200;
1<=n,k<=2000;
我们从小到大依次把数字插入到排列中,以这个思路进行dp。
dpi,j 表示插入了前i个数,产生的逆序对为j的排列的方案数;
考虑转移第i+1个数插在哪里,因为它比之前的都要大,插在最后面就\(dp[i+1][j+0]+=dp[i][j]\)表示不产生新的逆序对。
如果是最后一个数前面就是\(dp[i+1][j+1]+=dp[i][j]\),表示产生一个逆序对,倒数第2个数前面就是\(dp[i+1][j+2]+=dp[i][j]\),依次类推:
我们如果考虑dp[i][j]能从哪些状态转移过来,就可以前缀和优化。
\(dp[i][j]=\sum\limits_{k=0}^{i-1}dp[i-1][j-k]=sum[i-1][j]-sum[i-1][j-1]\)
\(sum[i][j]=\sum\limits_{k=0}^jdp[i][k];\)
单调队列维护
基本形式,适用范围
单调队列维护dp,一般就是把一个O(N)转移的dp通过单调队列优化成一个均摊O(1)转移的式子。
式子形如: dp[i]=max{f(j) }+g[i](这里的g[i]是与j无关的量),且j的取值是一段连续区间, 区间端点的两端随着i增大而增大的区间。
(同时如果这个可行的区间左端点固定,我们就可以通过之前讲的记录前缀最小值来处理)
这里的f(j)是仅和j有关的项。以下是常见的一维和二维的情况。
dp[i]=max{dp[j]+f(j)}+g[i] 或者 \(dp[level][i]\)=max{\(dp[level-1][j]\)+f(j)}+g(i)
这样的题我们就可以做单调队列优化
bzoj1855: 股票交易
我们考虑在未来T天内的某只股票,第i天的买入价为每股APi,第i天的卖出价为每股BPi(对于每个i,都有APi>=BPi),每天不能无限制地交易,规定第i天至多只能购买ASi股,至多卖出BSi股。另外规定在两次交易(买入或者卖出均算交易)之间,至少要间隔W天,也就是说如果在第i天发生了交易,那么从第i+1天到第i+W天,均不能发生交易。还规定在任何时间,一个人的手里的股票数不能超过MaxP。
初始w手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,问T天以后,小w最多能赚多少钱。
0<=W<T<=2000
设\(f[i][j]\)表示到第i天手里持有j的股票的最大收益,那么第i天有三种操作:
不买不卖:\(f[i][j]=f[i-1][j]\)
买入:\(f[i][j]=f[i-w-1][k]-ap[i]*(j-k)|k>=j-as[i]\)
卖出:\(f[i][j]=f[i-w-1][k]+bp[i]*(k-j)|k<=j+bs[i]\)
对于买入,我们对其变形:\(f[i][j]=f[i-w-1][k]-ap[i]*(j-k)=f[i-w-1][k]+ap[i]*k-ap[i]*j\)
那么可以用单调队列维护\(f[i-w-1][k]+ap[i]*k\)(因为对于固定的i,ap[i]是固定的),这样\(f[i][j]\)就能做到O(1)求得,而不必枚举k。卖出也一样。
bzoj3831: [Poi2014]Little Bird
有一排n棵树,第i棵树的高度是Di。
MHY要从第一棵树到第n棵树去找他的妹子玩。
如果MHY在第i棵树,那么他可以跳到第i+1,i+2,...,i+k棵树。
如果MHY跳到一棵不矮于当前树的树,那么他的劳累值会+1,否则不会。
为了有体力和妹子玩, MHY要最小化劳累值。
N(2<=N<=1 000 000)
设f[i]为MHY跳到第i棵树的最小代价;
f[i]=min(f[j]+1) i-k<=j<i;
f[i]=min(f[j]) i-k<=j<i&&h[j]>h[i];
发现上面那个东西用单调队列直接搞定,但下面那个不太好搞。不过发现由于h[j]>h[i]对答案的贡献至多为1,所以原来如果f[j]<f[j‘],==那么算上h[j]和h[j’]的影响后j仍然不会比j‘更差==,于是直接维护一个f递增的单调队列,其中当f相同的时候使h递减就行了。
送你一堆区间
送你在数轴上的 n 个区间和 m 个关键点, 你可以决定每个区间选或不选,问有多少种方案覆盖 所有的关键点.
对 1000000009 取模.
N<=5*10^5
Noip2008传纸条
一个m行n列的矩阵,而小渊和小轩传纸条。纸条从小渊坐标(1,1),传到小轩坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。
班里每个同学都可以帮他们传递,但只会帮他们一次。
全班每个同学有一个好心程度。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度之和最大。
n,m<=300
其实可以理解为从小渊到小轩传两次。
最暴力的做法:设\(dp[i][j][k][l]\)是第一张纸条到达(i,j),第二张到达(k,l)时最大权值。那么方程就是
\(dp[i][j][k][l] = map[i][j] + map[k][l] + max(dp[i - 1][j][k - 1][l],dp[i -1][j][k][l - 1],dp[i][j - 1][k -1][l],dp[i][j -1][k][l -1]);\)
还有一点注意的是,如果i == k && j == l,也就是第二张走了第一张的路径,那么就要减去, \(dp[i][j][k][l] -= map[i][j];\)
接下来枚举每个i,j,k,l,最后输出\(dp[m][n][m][n]\)就行了,但这样做时间复杂度是O(n^4)
其实我们可以让两个路线并行走,同时走。
而既然第一张与第二张是同时走,那么我们知道他们的步数是一样的,步数 = 横坐标+纵坐标,所以只需枚举i,j,k,就能计算出l,只需三重循环,时间就变成了O(n^3);
$dp[i][j][k] = map[i][j] + map[k][i+j-k] + max(dp[i - 1][j][k - 1],dp[i -1][j][k],dp[i][j-1][k -1],dp[i][j -1][k]); $
dp常见优化方法的更多相关文章
- SQL语句常见优化方法
Sql优化方法 先进行选择运算(where limit)再进行连接运算 where子句中应把过滤性最强的条件放在最前面 where子句中字段的顺序应和组合索引中字段顺序一致 使用索引 使用覆盖索引来避 ...
- 数据库sql常见优化方法
以前刚开始做项目的时候,开发经验尚浅,每次遇到查询比较慢时,项目经理就会问:是不是又用select * 了?查询条件有没有加索引?一语惊醒梦中人,赶紧检查..果然如此! 有时我们写sql语句时,没有考 ...
- MongoDB优化之一:常见优化方法
常用性能优化方案 创建索引 限定返回结果数 只查询使用到的字段 采用capped collection 采用Server Side Code Execution 使用Hint,强制使用索引 Hint ...
- Oracle SQL语句之常见优化方法总结
1.用EXISTS替换DISTINCT 当SQL包含一对多表查询时,避免在SELECT子句中使用DISTINCT,一般用EXIST替换,EXISTS(低效): SELECT DISTINCT USER ...
- Oracle SQL语句之常见优化方法总结--不定更新
1.SQL语句尽量用大写的: 因为oracle总是先解析SQL语句,把小写的字母转换成大写的再执行. 2.WHERE子句中的连接顺序: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理, ...
- MongoDB优化之二:常见优化方法
四个方面进行 cpu/io 方面的优化处理: 1.集群架构上进行读写分离.所有查询优先考虑在从库上读取,写操作在主库上执行.避免主库混合读写压力过大,也减少主库上读写记录的锁冲突. connectio ...
- web前端页面常见优化方法
(1)减少http请求,尽量减少向服务器的请求数量 (2)避免重定向 (3)利用缓存:使用外联式引用CSS.JS,在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏 ...
- 深度学习常见的优化方法(Optimizer)总结:Adam,SGD,Momentum,AdaGard等
机器学习的常见优化方法在最近的学习中经常遇到,但是还是不够精通.将自己的学习记录下来,以备不时之需 基础知识: 机器学习几乎所有的算法都要利用损失函数 lossfunction 来检验算法模型的优劣, ...
- 动态规划DP的优化
写一写要讲什么免得忘记了.DP的优化. 大概围绕着"是什么","有什么用","怎么用"三个方面讲. 主要是<算法竞赛入门经典>里 ...
随机推荐
- C# => 写法
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder ...
- C++:关键字explicit的用法
预测下面C++程序的输出: #include <iostream> using namespace std; class Complex { private: double real; d ...
- 【UOJ#129】 【NOI2015】寿司晚宴
题目描述 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 ...
- 论文阅读:Offloading Distributed Applications onto SmartNICs using iPipe
摘要: 包含丰富计算资源的新兴多核SoC SmartNIC具有卸载通用数据中心服务器任务的潜力,但是目前尚不清楚如何有效地使用SmartNIC并最大程度地减少卸载收益,尤其是对于分布式应用程序. 为此 ...
- Android 属性动画监听事件与一个菜单的例子
简单监听事件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 3 ...
- JavaWeb_(SSH论坛)_五、帖子模块
基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块 传送门 回复帖子 分析回 ...
- Linux上Redis安装和简单操作
Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- 基于Xposed hook 实时监测微信消息
本文以微信版本6.7.3为例进行分析有hook, 大部分做微信机器人的话,首先要实时抓取微信的消息,在这里展示三种方式对微信的消息进行hook: 1.基于UI层拉取加载进行监听 2.基于微信dao层调 ...
- 一、MongoDB为用户设置访问权限
MongoDB默认设置为无权限访问限制 注:基于Windows平台 MongoDB在本机安装部署好后 1. 输入命令:show dbs,你会发现它内置有两个数据库,一个名为admin,一个名为loca ...
- sql server中 设置与查看锁的超时时间(ZT) @@LOCK_TIMEOUT
在数据库的应用系统中,死锁是不可避免的.通过设置死锁的处理优先级方法,可以在数据库引擎中自动检测到死锁,对发生的死锁会话进行干预,从而达到解除死锁的目点,但在这种情况下,会话只能被动的等待数据库引 ...