算法技巧讲解》关于对于递推形DP的前缀和优化
这是在2016在长沙集训的第三天,一位学长讲解了“前缀和优化”这一技巧,并且他这一方法用的很6,个人觉得很有学习的必要。
这一技巧能使线性递推形DP的速度有着飞跃性的提升,从O(N2)优化到O(N)也不是不可能。
这一技巧的主要思想是使要加和的数据完全储存,并且在下一次计算中直接调用,所以你的对于DP当前项的查询无论是N还是logN,这一方法都能直接解决。
以一道题来作为我们的例子;
openjudge9277 (cf 295D跟这题差不多,只是对比于这道题要加个高度,但不用优化)
分享出题目
9277:Logs Stacking堆木头
- 总时间限制: 1000ms
- 内存限制: 131072kB
- 描述
-
Daxinganling produces a lot of timber. Before loading onto trains, the timberjacks will place the logs to some place in the open air first. Looking from the sideway, the figure of a logs stack is as follows:
We have known that the number of logs in each layer is fewer than the lower layer for at least one log, and that in each layer the logs are connected in a line. In the figure above, there are 12 logs in the bottom layer of the stack. Now, given the number of logs in the bottom layer, the timberjacks want to know how many possible figures there may be.
给出在最底层的木头的个数,问有多少种堆放木头的方式,当然你的堆放方式不能让木头掉下来.
在堆放的时候木头必须互相挨着在一起. - 输入
-
The first line of input contains the number of test cases T (1 <= T <= 1000000). Then T lines follow. Every line only contains a number n (1 <= n <= 200000) representing the number of logs in the bottom layer.
- 输出
-
For each test case in the input, you should output the corresponding number of possible figures. Because the number may be very large, just output the number mod 10^5.
- 样例输入
-
4
1
2
3
5 - 样例输出
-
1
2
5
34 - 提示
-
当输入3时,有5种方式
第一种:上面一个也不放
第二种:上面放一根,放在最左边
第三种:上面放一根,放在最右边
第四种:上面放二根
第五种:上面先放二根,然后在二根的上面放一根
那么对于这样一道比较裸的递推题,只要理解题意,推推样例画画图即可得动态转移方程:
但是,这道题的数据范围是20w,直接n2递推肯定过不了,所以我们通过计算前缀和可以得到一个更优的方法。
我们先来判断一下每一组答案是怎么来的
f[i]=f[i-1]*1+f[i-2]*2+f[i-3]*3+.....+f[1]*(i-1)
f[i+1]=f[i]*1+f[i-1]*2+f[i-2]*3+.......+f[1]*i
我们发现,f[i+1]只是在f[i]的基础上加了一组f[1]到f[i]的和,通过动态维护这一个和的结果,我们可以O(1)得出当前解。
所以现在只用考虑动态维护就好
来看张图
我们用f数组来计算当前解,用s数组来计算前缀和,这样就可以轻易的得出解啦
所以,在一般考试遇到这种题的时候,正常人花一定的时间都能算出简单的递推式,那么出题人也不傻,数据量会给的比较大,所以,这种前缀和优化就变得至关重要。决定了你究竟是那AC还是只拿暴力分。
下面给出代码
#include<stdio.h>
int f[],s,T,n;
int main()
{
int i,j;
f[]=,f[]=,s=;
for(i=;i<=;++i)
{
s+=f[i-];
s%=;
f[i]+=f[i-]+s;
f[i]%=;
}
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%d\n",f[n]);
}
return ;
}
算法技巧讲解》关于对于递推形DP的前缀和优化的更多相关文章
- [Codeforces676B]Pyramid of Glasses(递推,DP)
题目链接:http://codeforces.com/problemset/problem/676/B 递推,dp(i, j)表示第i层第j个杯子,从第一层开始向下倒,和数塔一样的题.每个杯子1个时间 ...
- openjudge1768 最大子矩阵[二维前缀和or递推|DP]
总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...
- 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
Pokémon GO Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 刷题向》关于一道比较优秀的递推型DP(openjudge9275)(EASY+)
先甩出传送门:http://noi.openjudge.cn/ch0206/9275/ 这道题比较经典, 最好不要看题解!!!!! 当然,如果你执意要看我也没有办法 首先,显然的我们可以用 f [ i ...
- 洛谷4316 绿豆蛙的归宿(DAG递推/概率dp)
题目大意: 给定一个DAG,求起点到终点的路径长度期望 根据题意可以知道每一条边都有一定概率被走到 那么\(\displaystyle\begin{aligned} Ans = \sum_{e \in ...
- Uva 10446【递推,dp】
UVa 10446 求(n,bcak)递归次数.自己推出来了一个式子: 其实就是这个式子,但是不知道该怎么写,怕递归写法超时.其实直接递推就好,边界条件易得C(0,back)=1.C(1,back)= ...
- 959F - Mahmoud and Ehab and yet another xor task xor+dp(递推形)+离线
959F - Mahmoud and Ehab and yet another xor task xor+dp+离线 题意 给出 n个值和q个询问,询问l,x,表示前l个数字子序列的异或和为x的子序列 ...
- hdu 4472 Count(递推即dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4472 代码: #include <cstdio> #include <cstring ...
- 洛谷 1192:台阶问题(递推,DP)
题目描述 有 N 级的台阶,你一开始在底部,每次可以向上迈最多 K 级台阶(最少 1 级),问到达第 N 级台阶有多少种不同方式. 输入输出格式 输入格式: 两个正整数N,K. 输出格式: 一个正整数 ...
随机推荐
- 移动元素时,translate要比margin好
比如 做全屏轮播时,父元素往往是被子元素撑起来的,那你设置父元素的margin时,往往会感染到子元素,如下图: 而用translate3d就不会出现这种效果:
- 预热篇- 总结Delphi Xe4 做App的的可行性分析. ios平台的问题还需要自行学习
首先澄清一个问题, 很多同学其实是误会了, 以为只要搞定了Delphi 就能很快写快餐程序了. ios 本身的知识还是需要一些的, 并没有什么捷径可以走. 但如果一个团队有分工协作的话, Delph ...
- 修改maven仓库位置
在eclipse中安装好maven2的插件后: 第一步: 默认会放在~/.m2/repository目录下 (“~”代表用户的目录,比如windows7下一般都是C:\Users\zz\.m2\rep ...
- LeetCode Replace Words
原题链接在这里:https://leetcode.com/problems/replace-words/description/ 题目: In English, we have a concept c ...
- matlab数据流仿真和时间流仿真
simulink 使用的动态系统仿真,仿真需要求状态方程和输出方程,关键是求状态方程,而状态方程的求解有多种算法,可变步长和定步长,所以仿真时对求解器的选择和步长的设置就比较重要. 所谓基於数据流的仿 ...
- 洛谷 P3144 [USACO16OPEN]关闭农场Closing the Farm_Silver
传送门 题目大意: n个谷仓 ,每次关闭一个谷仓,问剩下没被关闭的谷仓是 否联通. 题解:并查集+倒序处理 代码: #include<iostream> #include<cstdi ...
- 洛谷P3585 [POI2015]PIE
传送门 题目大意:有个n*m的格子图,要求'x'点要被染成黑色 有个a*b的印章,'x'是可以染色的印章上的点. 要求用印章去染色格子 (1)印章不可以旋转. (2)不能把墨水印到纸外面. (3)纸上 ...
- Django工程目录结构优化
1.我看到这篇文章,写的不错,在此复制了一份,防止以后找不到! 感谢作者的翻译--->原文的链接:http://www.loonapp.com/blog/11/ 如果原文存在,请打开原文件阅读 ...
- Yii登录验证和全局访问用户ID
注意:Yii默认的代码,Yii::app()->user->id返回的不是我们想要的用户ID,而是用户名.因此在useridentity类中要用一个变量来存储登录用户的ID,然后重载get ...
- java的内存管理 对象的分配与释放
分配 程序员通过new为每个对象申请内存空间(基本类型除外),所有对象都在堆中分配空间:释放:对象的释放是由垃圾回收机制决定和执行的. Java内存分为两种:栈内存和堆内存 (1)在函数中定义的基本类 ...