动态规划入门

伟大的acm大神谷哥教我学算法.

引例

斐波那契数

定义一个函数,f(x) = f(x-1) + f(x-2),x为正整数,定义f(1) = 1,f(2) = 1。给出整数n,求f(n)的数值。
直观的做法:

int f(int n)
{
    if(n==1||n==2)
        return 1;
    return f(n-1)+f(n-2);
}

思考:如果n为10^7程序还可以运行下去吗?(这里不考虑数据会爆int的问题)
显然效率低下.如下图所示:


beibo

我们可以看到计算f(n)的过程中有很多重复的计算。
这种做法的复杂度是指数级增长的!
进行优化,保存子状态,避免重复计算.

int f(int n){
    vector<int>F(n+1,0);
    F[1]=F[2]=1;
    for(int i=3;i<n;i++){
        F[i]=F[i-1]+F[i-2];
    }
    return F[n];
}

背包问题

有n个价值和体积分别为wi和vi的物品。从这些物品中挑选出总体积不超过V的物品,求所有方案中价值总和的最大值。
条件:
1≤ n ≤ 100
1≤ wi,vi ≤ 100
1 ≤ V ≤ 10000
wi,vi, V 均为整数

首先想到的是朴素递归:

rec(0,v)
int rec(int index,int capacity){
    if(index==n) return 0;
    else if(capacity<v[index]){
        return rec(index+1,capacity);
    }
    else{
        return max(rec(index+1,capacity),
                   rec(index+1,capacity-v[index])+w[index])
    }
}

思考:深搜的深度是n每一次搜索需要两个分支时间复杂度是O(2^n)n很大了之后怎么办?
来看一下rec函数的递归计算情况
例如:n=4,(w,v)={(3,2),(2,1),(4,3),(2,2)},V=5


rec

以上问题都存在着冗余重复的计算,每个都能划分成子问题解决.

DP

思想及概念

基本思想:一般求解最优化问题。将求解问题分解成若干个子问题,保存已解决的子问题的答案,在需要的时候直接利用。

特点:子问题重叠
子问题的重叠能更好地显示出动态规划的优势。因此可以打表记录子问题的答案。

性质:

  • 最优子结构:一个最优策略的子策略也是最优的。
  • 无后效性:过去的步骤只能通过当前的状态影响未来的发展,当前状态是历史的总结。

动态规划不是一种算法,而是一种思想,应用于有动态决策的问题当中。
动态规划的状态是人为定义的。
一般步骤:

  • 通过穷举计算过程图确定问题状态
  • 列出状态转移方程(决策)
  • 初始化和边界条件
  • 优化

LCS(最长公共子序列)

问题描述:给定两个字符串S,T(长度小于1000)。求出这两个字符串最长的公共子序列的长度。
思考举例:


lcs

对于X和Y,我们试着计算X[1:i]与Y[1:j]的最长公共子序列。

lcs2

因此, 我们可以得到递推方程:

lcs3

dp[i][j]为序列 (X1, X2, …, Xi)和 (Y1, Y2, …, Yj)的最长公共子序列的长度。

LIS(最长上升子序列)

给出一个由n个数字成的序列A[1:n],找出它的最长单调上升子序列。即求最大的m

使得a1<a2<…<am且A[a1]<A[a2]<…<A[am]

思考:先举出个例子 A[1:9] = 2 1 5 3 6 4 8 9 7。我们首先考虑A[1:i]的LIS,
令A[1:i]的LIS为dp[i].比如i=6,这时候A[i] = 4, 我们往i左边看。

lis

从上边的规律我们可以写出状态转移方程:

lis2

思考:这个算法的复杂度为O(N^2),还能做的更快吗?

对于这个例子 A[1:9] = 2 1 5 3 6 4 8 9 7
当i=6时,我们已经算出dp[3] = dp[4] = 2
其中j = 3,对应的序列为 {1, 5}
j = 4,对应的序列为 {1, 3}
其实我们更倾向要{1, 3},因为对于dp值为 2的情况A[j]越小,越有潜力被利用上进行更新。
因此我们重新开一个数组g,保存dp值为k的对应的数组A中的最小值。因此当i=6时,
g数组中有两个值,即g[1]=1,g[2]=3。
在计算dp[6]的时候只要用g数组中的值更新就好。

数组g,保存dp值为k的对应的数组A中的最小值。
g[1]<=g[2]<=……<=g[k]
计算dp[i]: 在g中找到大于等于A[i]的第一个数j, 则dp[i] = j更新g: 由于g[j]>A[i],则需要更新g[j] = A[i].

file(g,g+n,INFINITY);
for(int i=0;i<n;i++){
    int j=lower_bound(g,g+n,A[i])-g;
    dp[i]=j+1;
    g[j]=A[i];
}

由于g是有序的,查找利用二分查找。总体复杂度为 O(n logn)

背包问题0/1

有n个价值和体积分别为wi和vi的物品。从这些物品中挑选出总体积不超过V的物品,求所有方案中价值总和的最大值。

条件:
1≤ n ≤ 100
1≤ wi,vi ≤ 100
1 ≤ V ≤ 10000
wi,vi, V 均为整数

观察这个题目的特点:

  • V不超过10000
  • 整数

引例中朴素方法有很多重复计算。
引例中的状态是2维的(前index个背包,剩下容积)
引入dp[i][j],表示前i个物品中用了容积j获得的最大价值。

递归方程为:

beibao01

复杂度为O(n*V)

总结

动态规划是一种思想。动态规划有很多类型(如普通DP, 树形DP,状压DP,按位DP,插头DP等);

动态规划思想的养成不可能一蹴而就,而是慢慢养成的。养成的过程需要不断增加题目的见识面,不能局限于几种类型的DP;

学好DP需要下很大功夫。同样的, 学好DP,会对个人算法素养提升很大。而且,DP也是面试中常见的考点

参考:
《算法竞赛入门经典》…………刘汝佳 等
《ACM竞赛基础教程》………...俞经善 等
《编程之法》……………………July
http://blog.csdn.net/zsc09_leaf/article/details/6536802
http://poj.org/problem?id=1458
http://poj.org/problem?id=3254
http://blog.csdn.net/y990041769/article/details/24658419

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容