动态规划算法

简介:
斐波纳契数列F(n)

n

0

1

2

3

4

5

6

7

8

9

10

F(n)

1

1

2

3

5

8

13

21

34

55

89

递归 vs 动态规划

递归版本(太慢):

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

动态规划版本(有效率!算法复杂度是 O(n)):

int a[1000];
int f(int n)
{
    a[0]=a[1]=1;
    for(int i=2; i<=n; i++)
        a[i]=a[i-1]+a[i-2];
    return a[n];
}

方法概要

构造一个公式,它表示一个问题的解是与它的子问题的 解相关的公式.   E.g.  F(n) = F(n-1) + F(n-2).

为这些子问题做索引 ,以便它们能够在表中更好的存储与检索 (i.e., 数组array[])

以自底向上的方法来填写这表格; 首先填写最小子问题的解.

这就保证了当我们解决一个特殊的子问题时, 可以利用比它更小的所有可利用的 子问题的解.

动态规划算法原理

算法思想:

将待求解的问题分解成若干个子问题,并存储子问题的解而避免计算重复的子问题,并由子问题的解得到原问题的解。

动态规划算法通常用于求解具有某种最优性质的问题。

动态规划算法的基本要素:最优子结构性质和重叠子问题。

原理:

最优子结构性质:问题的最优解包含着它的子问题的最优解。即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。

重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些问题被反复计算多次。对每个子问题只解一次,然后将其解保存起来,以后再遇到同样的问题时就可以直接引用,不必重新求解。

解决问题的基本特征:

1. 动态规划一般解决最值(最优,最大,最小,最长……)问题;

2. 动态规划解决的问题一般是离散的,可以分解(划分阶段)的;

3. 动态规划解决的问题必须包含最优子结构,即可以由(n-1)的最优推导出n的最优

解决问题的基本步骤:

动态规划算法的4个步骤:

1. 刻画最优解的结构特性. (一维,二维,三维数组)

2. 递归的定义最优解. (状态转移方程)

3. 以自底向上的方法来计算最优解.

4. 从计算得到的解来构造一个最优解.

举例实战

例题一.   斐波纳契数列F(n)

步骤1:用F(n)表示在斐波纳契数列中第n个数的值;

步骤2:状态转移方程:

 

步骤3:以自底向上的方法来计算最优解

n

0

1

2

3

4

5

6

7

8

9

10

F(n)

1

1

2

3

5

8

13

21

34

55

89

步骤4:在数组中分析构造出问题的解;

例题二.   输入n,求出n!

步骤1:用F(n)表示n!的值;

步骤2:状态转移方程:

步骤3:以自底向上的方法来计算最优解

n

0

1

2

3

4

5

6

7

8

9

10

F(n)

1

1

2

6

24

120

720

       

例题三:排队买票问题

一场演唱会即将举行。现有n个歌迷排队买票,一个人买一张,而售票处规定,一个人每次最多只能买两张票。假设第i位歌迷买一张票需要时间 Ti(1≤i≤n),队伍中相邻的两位歌迷(第j个人和第j+1个人)也可以由其中一个人买两张票,而另一位就可以不用排队了,则这两位歌迷买两张票的时 间变为Rj,假如Rj<Tj+Tj+1,这样做就可以缩短后面歌迷等待的时间,加快整个售票的进程。现给出n, Tj和Rj,求使每个人都买到票的最短时间和方法。

分析:

如果前i个人买票的最优买票方式一确定,比如第i-1个人买一张票,则前i-1个人的买票方式也一定是最优的。即问题的最优解包含子问题的最优解。

步骤1:用F(i)表示前i个人买票的最优方式,即所需最短时间;现在要决定F(i)需要考虑两种情况:

(1)第i个人的票自己买

(2)第i个人的票由第i-1个人买

步骤2:状态转移方程:

步骤3:以自底向上的方法来计算最优解

程序的实现(伪代码):

BuyTicks(T, R)
1    n ← length[T] 
2    f[0] ← 0
3    f[1] ← T[1]
4    for i ← 2 to n do 
5                 f[i] ← f[i-2]+R[i-1]
6                 if  f[i] > f[i-1]+T[i] then 
7                     f[i] ← f[i-1]+T[i]
8    return f
目录
相关文章
|
21天前
|
算法
算法修炼-动态规划之路径问题(1)
算法修炼-动态规划之路径问题(1)
|
1月前
|
算法
【算法】——动态规划题目讲解
【算法】——动态规划题目讲解
|
1月前
|
算法 测试技术 索引
动态规划算法练习题
动态规划算法练习题
20 0
|
2月前
|
算法 JavaScript Java
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
|
2月前
|
机器学习/深度学习 算法 测试技术
【动态规划】【C++算法】2742. 给墙壁刷油漆
【动态规划】【C++算法】2742. 给墙壁刷油漆
|
2月前
|
算法 测试技术 C++
【动态规划】【状态压缩】【C++算法】1815 得到新鲜甜甜圈的最多组数
【动态规划】【状态压缩】【C++算法】1815 得到新鲜甜甜圈的最多组数
|
2月前
|
算法 测试技术 C++
【动态规划】【中位数】【C++算法】1478. 安排邮筒
【动态规划】【中位数】【C++算法】1478. 安排邮筒
|
2月前
|
算法 测试技术 C++
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
|
1月前
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
6天前
|
算法
算法系列--动态规划--背包问题(5)--二维费用背包问题(上)
算法系列--动态规划--背包问题(5)--二维费用背包问题(上)
14 0