学习qzz的命名,来写一篇关于动态规划(dp)的入门博客。

动态规划应该算是一个入门oier的坑,动态规划的抽象即神奇之处,让很多萌新 萌比。

写这篇博客的目标,就是想要用一些容易理解的方式,讲解入门动态规划的真正意义。

奶萌兔的温馨提示:建议先理解dfs哦~(本文以一种较为新奇的方式解释DP)

动态规划

那什么是动态规划?

来问问神奇的奶萌兔吧(强行盗梗)!

(奶萌兔来给你讲解啦~虽然还在睡觉=w=)

动态规划(英语:Dynamic programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划常常适用于有重叠子问题[]和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。
通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。
这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。----来自wiki百科

说这么多,DP能干什么?

奶萌兔的回答:解决一些问题...解决一些,dfs效率无法通过的问题。

不如先讲一道例题:

例1

  爬楼梯:现在有n层楼梯,奶萌兔位于第0层 现在奶萌兔每一次可以往上爬1层或者2层,问奶萌兔爬到第n层有多少种方案?

这是一道经典的入门题,对于这道题,我们由简入深。

  如何dfs?

  这样考虑 dfs(int dep) 表示奶萌兔在第dep层。

  那有两个走法,一个是dfs(dep+1) 一个是dfs(dep+2)。

  而dfs的边界呢? 则是 n 。 即 if (dep>n) return;

  初始值? dfs(0) 从第0层开始。

  对于答案的统计? 那就是每当dep为n时,说明到达了对ans统计加1。 即 if (dep==n) ans++ 且return;

  说了怎么多dfs?对dp有个什么用啊!!!

  这时候,奶萌兔来引入一个东西——状态。

  状态是什么?用浅显易懂的解释就是,dfs需要保存的东西(不一定...),如dfs(int dep)  dep(奶萌兔当前的层数)就是一个状态。

  而dp则是利用状态之间的相互关联,答案得以更新。

  那下面,来讲 如何dp?

  这样考虑 DP[dep] 表示奶萌兔从第0层走到第dep层时的方案数

  依旧有两个走法,一个是DP[dep+1] 一个是DP[dep+2]。

  是不是和dfs很相似? 接下来是重点。

  初始值 dp[0]=1 到第0层有一种方案,就是一开始就在0层。

  DP[dep+1] DP[dep+2]会等于什么?

  DP[dep+1]+=DP[dep] DP[dep+2]+=DP[dep]

  因为走到第dep层的方案是DP[dep],那么在走一层的时候,就只能走到dep+1的地方,那么dep上的全部方案,在通过走一步这样唯一的一个方法,可以到达dep+1,所以走到dep+1包含了dep上的方案,dep+2同理。

  上面的两个式子就是状态转移方程了。

  简单的转化一下, dp[dep+1]+=dp[dep] dp[dep+2]+=dep[dep] 则dp[dep]=dp[dep-1]+dp[dep-2] (当然不转化也是可以的,但对于部分题目,一些转化之后可能可以因此优化效率)

例2

  从一个一维的题目,试试跳到二维。

  骑士遍历:第一问可以直接往字典序最小去dfs,所以直接关注第二问吧

第二问:给一个n*m的棋盘,给定起点x1,y1 终点 x2,y2 在只能走日且只能向右走的情况下,问方案数。

这是例1的拓展,从一维的向上走,变为二维的向右走。

首先对于这样的棋盘,我们是不习惯的,因为与我们的数组顺序不同,让人烦心。

那怎么办捏?问问神奇的奶萌兔!

奶萌兔幽幽的说了一句:对~称~旋~转~

 哈!这是原来的题

哈!这还是原来的题

于是旋转一下之后,棋盘还是原来的棋盘,只是方向改变了。

题目就变成了只走日字且向下走的情况。

  老规矩呢,如何dfs?

  用用新名词,状态,dfs的状态是什么? dfs(int x,int y) 表示当前奶萌兔骑士在(x,y)的位置。

  那就是有四个走法

  dfs(x+1,y+2)  dfs(x+2,y+1)   dfs(x+1,y-2) dfs(x+2,y-1)

  边界 0 ,n    0 ,m 即 x>0且x<=n    y>0且y<=m

  初始:dfs(x1,y1)

  答案的统计:每当 x==x2&&y==y2 时说明到终点了,那ans++

  dp类比就好啦,状态就是数组的下标。

  DP[x][y] 表示奶萌兔骑士从(x1,y1)出发到(x,y) 的位置时的方案。

  一样四个走法

  DP[x+1][y+2] DP[x+2][y+1]  DP[x+1][y-2] DP[x+2][y-1]

  边界是一样的哦~

  初始:DP[x1][y1]=1 (在起点的时候就是一个方案)

  答案:DP[x2][y2]

  那转移方程,和例1一样哦,只是拓展为二维,走法变多一些。

  DP[x+1][y+2]+=DP[x][y]     DP[x+2][y+1]+=DP[x][y]    DP[x+1][y-2]+=DP[x][y]     DP[x+2][y-1]+=DP[x][y]

  简单转化一下: dp[x][y]=dp[x-1][y-2]+dp[x-2][y-1]+dp[x-1][y+2]+dp[x-2][y+1];

  好了问题来了:怎么转化的? 不妨这样撕烤,固定住(x,y) 找找哪些点能到(x,y) 那些点的方案数加起来就是了(或者,对前面的方程变化,x+d改为x-d,y+d改为y-d  (d为常数))。

 #define ll long long
#include<cstdio>
#include<iostream>
using namespace std;
ll f[][];
int ansx[],ansy[];
int n,m,x1,x2,y1,y2;
const ll HR=1e18;
void dfs(int dep,int nowx,int nowy){
ansx[dep]=nowx;
ansy[dep]=nowy;
if (nowx==n&&nowy==m) {
for (int i=;i<dep;i++)
printf("(%d,%d)-",ansx[i],ansy[i]);
printf("(%d,%d)",ansx[dep],ansy[dep]);
exit();
}
//dfs的顺序注意按字典序最小。
if (nowx+<=n&&nowy->) dfs(dep+,nowx+,nowy-);
if (nowx+<=n&&nowy+<=m) dfs(dep+,nowx+,nowy+);
if (nowx+<=n&&nowy->) dfs(dep+,nowx+,nowy-);
if (nowx+<=n&&nowy+<=m) dfs(dep+,nowx+,nowy+);
}
int main(){
scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2);
if (x1==) {
dfs(,,); //第一问
printf("NO");
return ;
}
//第二问
f[x1][y1]=;
for (int i=x1+;i<=x2;i++){ //从x1+1开始,因为x1这一行是不可能更新的。
for (int j=;j<=m;j++){
if (j->) f[i][j]+=f[i-][j-]; //边界
f[i][j]%=HR;
f[i][j]+=f[i-][j+];
//为什么这个不判?原因是f[i-1][j+2]的值一定是0,因为无法更新到边界外的数,而初始值都是0,注意把数组开大即可,下面同理
f[i][j]%=HR;
f[i][j]+=f[i-][j-];
f[i][j]%=HR;
f[i][j]+=f[i-][j+];
f[i][j]%=HR;
}
}
printf("%lld",f[x2][y2]);
return ; }

例2

以上就是入门的方案数dp。

后期可能更新其他dp呀~

初探动态规划(DP)的更多相关文章

  1. 动态规划dp

    一.概念:动态规划dp:是一种分阶段求解决策问题的数学思想. 总结起来就一句话:大事化小,小事化了 二.例子 1.走台阶问题 F(10):10级台阶的走法数量 所以:F(10)=F(9)+F(8) F ...

  2. 算法-动态规划DP小记

    算法-动态规划DP小记 动态规划算法是一种比较灵活的算法,针对具体的问题要具体分析,其宗旨就是要找出要解决问题的状态,然后逆向转化为求解子问题,最终回到已知的初始态,然后再顺序累计各个子问题的解从而得 ...

  3. 初探 插头DP

    因为这题,气得我火冒三丈! 这数据是不是有问题啊!我用cin代替scanf后居然就AC了(本来一直卡在Test 18)!导致我调(对)试(排)了一个小时!! UPD:后来细细想想,会不会是因为scan ...

  4. 【转】动态规划DP

    [数据结构与算法] DP 动态规划 介绍 原创 2017年02月13日 00:42:51 最近在看算法导论. DP全称是dynamic programming,这里programming不是编程,是一 ...

  5. 动态规划DP的优化

    写一写要讲什么免得忘记了.DP的优化. 大概围绕着"是什么","有什么用","怎么用"三个方面讲. 主要是<算法竞赛入门经典>里 ...

  6. hdu 1421:搬寝室(动态规划 DP + 排序)

    搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. hdu 2059:龟兔赛跑(动态规划 DP)

    龟兔赛跑 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissi ...

  8. Luogu 2627 修建草坪 (动态规划Dp + 单调队列优化)

    题意: 已知一个序列 { a [ i ] } ,求取出从中若干不大于 KK 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...

  9. 动态规划DP入门

    百度百科↓ 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.20世纪50年代初美国数学家R.E.Bellman ...

随机推荐

  1. WEB安全第三篇--控制请求的艺术:CSRF和SSRF

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...

  2. fluentValidation集成到autofac

    废话不说直接上代码 // 首先实现ValidatorFactory public class DependencyResolverValidatorFactory : ValidatorFactory ...

  3. 【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树

    [BZOJ3545][ONTAK2010]Peaks Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困 ...

  4. HTML5+CSS3 表格设计(Table)

    <style> body { width: 600px; margin: 40px auto; font-family: 'trebuchet MS', 'Lucida sans', Ar ...

  5. Mysql limit offset用法举例

    转自:http://blog.csdn.net/iastro/article/details/53037600 Mysql limit offset示例 例1,假设数据库表student存在13条数据 ...

  6. Python 自学积累(一)

    1. 当"print os.path.dirname(__file__)"所在脚本是以完整路径被运行的, 那么将输出该脚本所在的完整路径,比如: python d:/pythonS ...

  7. 转载:隐式Intent

    一.隐式意图介绍 显式意图我们前面已经提到,形如: Intent intent = new Intent(); intent.setClass(this,Other.class); //此句表示显式意 ...

  8. Mssql备份失败

    Mssql备份失败出现如下提示 备份时先删除默认的备份设备,自己选择路径

  9. FZU 1064 教授的测试(卡特兰数,递归)

    Problem 1064 教授的测试 Accept: 149 Submit: 364 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Des ...

  10. Apache 2.4 编码GB2312中文乱码的问题

    今天部署了一个项目,代码和数据库都是gb2312的,本地和服务器都是apache2.4的版本,本地编码没问题,response的content-type是空的.按html的mete解析的,查看源码也是 ...