动态规划初步
@
1.递推
讲到动态规划就不得不提到递归,递推是经常被使用的一种简单算法。递推 是一种用若干步可重复的简单运算来描述复杂问题的方法。递推的特点在于,每一项都和他前面的若干项有一定关联,这种关联一般可以通过 递推关系式 来表示,可以通过其前面若干项得出某项的数据。对于递推问题的求解一般从初始的一个或若干个数据项出发,通过递推关系式逐步推进,从而得出想要的结果,这种求解问题的方法叫递推法。其中,初始的若干数据项称为边界。
例题:兔子问题
Description
有一种兔子,出生后一个月就可以长大,然后再过一个月一对长大的兔子就可以生育一对小兔子且以后每个月都能生育一对。现在,我们有一对刚出生的这种兔子,那么,n 个月过后,我们会有多少对兔子呢?假设所有的兔子都不会死亡。
Input
输入文件仅一行,包含一个自然数 n。
Output
输出文件仅一行,包含一个自然数,即 n 个月后兔子的对数。
Sample Input 1
1
Sample Output 1
1
Sample Input 2
3
Sample Output 2
2
Source
一本通
这道题虽然有规律,可以直接用公式算出来,但我们还是要知道用递推的做法。
(因为作者懒,所以只讲核心部分)
f[1] = 1, f[2] = 1;
for(int i = 3;i <= n; ++i) {
f[i] = f[i-1] + f[i-2];
}
// f[n] 即为所求。
不用思考版(滑稽一波):
#include <bits/stdc++.h>
using namespace std;
int a[110];
int fid(long long n){
if (a[n]==0){
a[n]=fid(n-1)+fid(n-2);
}
return a[n];
}
int main(){
a[1]=a[2]=1;
int n;
cin >> n;
cout << fid(n);
return 0;
}
2.动态规划入门
动态规划的科普
动态规划 是编程解题的一种重要手段。1951 年美国数学家 R.Bellman 等人,根据一类多阶段问题的特点,把多
阶段决策问题变换为一系列互相联系的单阶段问题,然后逐个加以解决。与此同时,他提出了解决这类问题的“最
优化原理”,从而创建了解决最优化问题的一种新方法:动态规划。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于
一个值,我们希望找到具有最优值的解。
所以说动态规划是个好东西。
动态规划的基本概念:
阶段:把所给问题的求解过程恰当地分成若干个相互联系的阶段,以便于求解。过程不同,阶段数就可能不
同。描述阶段的变量称为阶段变量,常用 表示。阶段的划分,一般是根据时间和空间的自然特征来划分,
但要便于把问题的过程转化为多阶段决策的过程。
状态:状态表示每个阶段开始面临的自然状况或客观条件,它不以人们的主观意志为转移,也称为不可控因
素。通常一个阶段有若干个状态,状态通常可以用一个或一组数来描述,称为状态变量。
决策:表示当过程处于某一阶段的某个状态时,可以做出不同的决定,从而确定下一阶段的状态,这种决定
称为决策。不同的决策对应着不同的数值,描述决策的变量称决策变量。
状态转移方程:动态规划中本阶段的状态往往是上一阶段的状态和上一阶段的决策的结果,由第 i段的状态
dp[i],和决策 u[i]来确定第 i+1段的状态。状态转移表示为F(i + 1) = T(f(i), u(i)) ,称为状态转移方程。
策略:各个阶段决策确定后,整个问题的决策序列就构成了一个策略,对每个实际问题,可供选择的策略有
一定范围,称为允许策略集合。允许策略集合中达到最优效果的策略称为最优策略
动态规划的优化原理与无后效性。
最优化原理:“一个过程的最优决策具有这样的性质:即无论其初始状态和初始决策如何,其今后诸策略对以
第一个决策所形成的状态作为初始状态的过程而言,必须构成最优策略”。也就是说一个最优策略的子策略,
也是最优的。
无后效性:如果某阶段状态给定后,则在这个阶段以后过程的发展不受这个阶段以前各个状态的影响。