动态规划

动态规划

好吧,其实算是复习的。

动态规划(Dynamic Programming,简称DP),是指一种解决特定问题的一种方法。其通过将一个大问题拆分成多个较为简单的小问题,大问题的最优解由小问题的最优解合并而来的方式动态的解决问题。

首先,有几个概念需要阐述:

  1. 阶段:将所给问题的求解过程恰当的分成多个相互联系的阶段,以便于求解,即拆分而来的多个子问题。
  2. 状态:表示每个阶段开始时进行转移到下一个状态所需的条件,通常,一个阶段具有多个状态。
  3. 决策:当处于某一阶段的某一状态时,可以做出不同的决定,从而确定下一阶段的状态,这种决定称为决策,描述决策的变量称为决策变量。
  4. 状态转移方程:在 \(DP\) 中本阶段的状态通常由上一阶段的状态和决策转移而来,由第 \(i\) 步的状态 \(f(i)\) ,和决策 \(u(i)\) 来确定第 \(i+1\) 段的状态。表示为 \(F(i+1)=T(f(i),u(i))\) ,这称为状态转移方程。

其次,要解决的问题必须符合两个性质才可以使用动态规划

  • 无后效性:本阶段之前做出的决策不会影响之后的决策进行
  • 最优子结构:即本阶段的最优解也是全局最优解,也就是全局最优解由局部最优解合并而来。

例题:

1.硬币问题:

题目描述:今有面值为 1、5、11 元的硬币各无限枚。想要凑出 \(n\) 元,问需要的最少硬币数量。

由于币值并不太完美,导致贪心的做法会被 \(hack\) 掉,考虑使用 \(DP\) 的方式,设 \(dp[i]\) 表示凑 \(i\) 元钱所需的最少钱币数,则其可以由其之前的三种状态转移而来,即 \(dp[i-1],dp[i-5],dp[i-11]\) 三种状态转移而来,则其的状态转移方程为

\[dp[i]=min(dp[i-1],dp[i-5],dp[i-11])+1 \]

\(O(n)\) 的复杂度即可解决问题,非常好复杂度,这使时限旋转。

2.序列问题

(1.)最大子段和问题:

题目描述:给出一个长度为 \(n\) 的序列 \(a\) ,选出其中连续且非空的一段使得这段和最大。

\(dp[i]\) 表示以 \(i\) 结尾的最大子序列和,则其由上一最大子序列和转移而来或其自己为最大子段和。可推出其状态转移方程为

\[dp[i]=max(dp[i],dp[i-1]+dp[i]) \]

\(O(n)\) 扫一遍即可。

(2.)最长连续上升子序列(LIS):

题目描述:给出一个长度为 \(n\) 的序列 \(a\) ,选出其中连续且非空的一段使这一段上具有 \(a_i<a_j(i<j)\)

\(dp[i]\) 表示以 \(i\) 结尾的最长连续上升子序列。考虑如何进行状态转移,如果 \(a[i]>a[i-1]\) 则有 \(dp[i]=dp[i-1]+1\) ,此时考虑边界问题,由于最长上升子序列最短为一,则初始化时 \(dp[i]=1\) 。则得出状态转移方程:

\[dp[i]=max(dp[i],dp[i-1]+1)(a[i]>a[i-1] \]

同样是 \(O(n)\) 的复杂度。

(3.)最长公共子序列(LCS):

题目描述:给予两个字符串 \(s1,s2(s1=x_1,s_2,x_3...x_m|s2=z_1,z_2,z_3...z_k)\) ,存在一个严格递减的下标序列 \(<i_1,i_2,i_3,...,i_k>\) 使得对于所有 \(j=1,2,3...k\) 有:\(s1_{[i,j]}=s2_j\)

\(dp[i][j]\)\(s1\)\(i\) 位到 \(s2\)\(j\) 的最长公共子序列,若有 \(s1_i=s2_j\) 则有 \(dp[i][j]=dp[i-1][j-1]+1\) ,若无,则有 \(dp[i][j]=max(dp[i-1][j],dp[i][j-1])\) ,得出状态转移方程:

\[dp[i][j]=\begin{cases}d[i-1][j-1]+1 &s1[i]=s2[j]\\max(dp[i][j-1],dp[i-1][j])&s1[i] \ne s2[j]\end{cases} \]

3.背包问题:

(1.)01背包问题:

题目描述:一个旅行者有一个最多能装 \(M\) 公斤的背包,现在有 \(n\) 件物品,它们的重量分别是 \(W_1,W_2...W_n\) 它们的价值分别为 \(C_1,C_2...C_n\) ,求旅行者能获得最大总价值。

对于每一个物品,有两种状态(取或不取),其实这也就得出了状态转移方程

\[dp[i]=max(dp[i],dp[i-w[i]]+c[i]) \]

(2.)完全背包问题

题目描述:设有 \(n\) 种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为 \(M\) ,今从 \(n\) 种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于 \(M\) ,而价值的和为最大。

其实是01背包问题的一种子问题,即讨论每个物品取几个,多一层循环讨论取几个即可。

\[dp[i]=max(dp[i],dp[i-k*w[i]]+k*c[i])(j>=k*w[i]) \]

ok,先写到这,剩下以后再写,润了。

posted @ 2024-10-12 09:15  adsd45666  阅读(21)  评论(0编辑  收藏  举报