讲义 GDFZOJ 【36】 动态规划基础1

动态规划基础1

【传送门】

T1 滑雪

难度:普及-, 做法:记忆化搜索

首先(for)一遍起点,分别使用(dfs)搜索,搜索过程记录答案,大大减少复杂度。


T2 最长下降子序列

难度:普及-, 做法:动态规划

(dp_{i}) 为以 (a_i) 结尾的最长上升子序列的长度,不难得出状态转移方程为 (dp_j=max(dp_j, dp_i+1) (1 leq i leq n, 1 leq j < i, a_i<a_j))


T3 简单传纸条

难度:入门+, 做法:你猜

很显然这题的做法是 dfs (DP) 。设 (dp_{i,j}) 为走到坐标 ((i,j)) 的最小八卦值之和。那么由于点 ((i,j)) 只能由点 ((i-1,j))((i,j-1)) 到达,所以状态转移方程为 (dp_{i,j}=min(dp_{i-1,j},dp_{i,j-1}+a_{i,j}))


T4 数字三角形

难度:NOI/NOI+/CTSC, 做法:膜你退火 记忆化搜索

这是(IOI 1994)原题。

做法为从顶端的点开始向下(dfs),回朔时记录下当前点的答案,以此避免 (O(2^n)) 的暴力搜索,时间复杂度变为 (O(n^2))


T5 递归函数

难度:普及-, 做法:(伪)暴力

直接将递归公式原原本本抄下来,加上记忆化即可。

注:需要一定的玄学优化,不然会不明不白地TLE


T6 雷曼兔

题目传送 戳这

前置知识:线性dp

贪心看似有显然的策略(即每一次寻找受益最大的点,然后跳过去)
很遗憾,手玩了几组样例后就心灰意冷

就只好向dp的方向思考
首先这是一道 基础的 线性dp(相信聪明的你看得出来)

  • 定义: (dp[i]) 表示从i层到最底层的最大华丽度总和
  • 初始化:从(i)层直接到(1)层的华丽度
  • 状态转移方程: (dp[i]=max{dp[j]+v}) (very important)
    由于(v=(|x1-x2|+|y1-y2|)^2),所以(v)始终大于(0),dp([n * n])即为答案!
    题做完了!!

T7 核电站问题

题目传送 戳这

前置知识:线性dp

这还是一道线性dp(好吧,直接深搜也可以AC

  • 定义: (dp[i])表示放到第i个坑时的总方案数。
  • 考虑任意i:
  • (i le m) 的时候,也就是说总数比核物质要少,这样子怎么样组合也不会爆炸
  • 当$ i==m$ 的时候,只会有一种情况——这i个位置全是核物质,所以要减去1
  • 当$ i gt m $ 的时候,这时候就要考虑爆炸的情况了下面来讨论这个递推式

我们的思路是拿每一次情况减去这次要减去行不通(爆炸)的情况,因为每一次都考虑前面不行的情况所以接下来循环只需要考虑这次不行的情况,总情况为(2 * a[i-1])

我们给第i为设置一个放和不放的状态,也就是(0)(1)(1)为核物质,(0)为木有),前面(i-1)已经考虑好了,都可以放,所以先不用处理加上这第(i)位的情况,根据组合原理,第i位两种情况所以一共(2 * a[i-1])种情况,接下来就是处理不行(爆炸)的情况

当循环到第(i)位的时候,会爆炸的情况就是前面已经有(m-1)(1)(核物质),但这里(m-1)(1)的前面那一位一定不是(1)!,若为(1)的话早就在前面达到(m)的情况下已经处理((-))过了,所以前面从开始数一共(i-1-m)位是可以任意组合 的,(01001001…)任意,因为前面是不会有核物质爆炸的,根据组合原理到达(m)个爆炸的一共有前面(i-1-m)个数的组合,所以减去(a[i-1-m])


T8 统计单词个数

题目传送 戳这

前置知识:哈希,二维dp

1.审题

简明题意

给出一个字符串,将其分成k段,使每份中包含的单词个数加起来总数最大

2.思路

不会处理字符串,如何判重?

哈希!!

先定义状态:

  • (dp[i][j])表示分到第i个位置,分了j次的最优解
  • (map[i][j])表示在从i到j的区间里有合法的子串的个数

预处理:分别把每一个子串哈希一遍和目标串匹配,匹配完成将这一段加1;状态转移方程:(dp[i][j]=max(dp[i][j],dp[1~i-1][j-1])),特别地:当j=1时,(dp[i][1]=map[0][i])


T9 环形石子归并

题目传送 戳这

前置知识:区间dp,前缀和

思路

最小得分? 难道是贪心

贪心显然不能,因为只有相邻两堆才能合并!

(Hack)

5
8 4 6 3 5

所以,此题正解是区间$dp $

定义((ilt j) ):

  • (dp1[i][j])表示把从i到j的石子合并为一堆的最小得分
    状态转移方程:(dp1[i][j]=min(dp1[i][j],dp1[i][k]+dp1[k+1][j]+a[i]+a[i+1]+……+a[j])),我们发现要求一段区间和,所以毫不犹豫上前缀和,dp要先枚举dp区间的长度,再枚举左端点,右端点也可以求出来,再枚举k。

T10 乘法游戏

题目传送 戳这

前置知识:区间(dp)

1.审题

简明题意

给出一串数,取出一个数(不能是头和尾),将获得的收益是它左边,右边和它自己的乘积。求最小收益。

2.思路

考虑一个区间的最优解,设这一段长度为L,最终要求的是长度为n的那段的最优解。
令这个区间为([i,j]),则([i,j])中取一点(k(ilt klt j))
那i~j区间的最优解就是([i,k])区间的最优解加上([k+1,j])区间的最优解再加上合并这两个区间所需的代价。
但是要([i,j])区间最优,所以要枚举(k)([i+1,j-1])的所有情况,取最优的那一组。
定义:(dp[i][j])表示([i,j])区间的最优解
状态转移方程:

[dp[i][i + k - 1] = dp[i][j] + dp[j][i + k - 1] + (a[i] * a[i + k - 1] * a[j]) ]

原文地址:https://www.cnblogs.com/zhnzh/p/13431536.html