🥹含泪总结周赛中的三道「DP」问题

6100. 统计放置房子的方式数

6107. 不同骰子序列的数目

5229. 拼接数组的最大分数

统计放置房子的方式数

题目详情可见 统计放置房子的方式数

对于计数问题,大多数都是用「动态规划」

本题在理解上不难,就是求出街道一边所有符合要求的排列数量。同理,另一边排列数量是相等的!

但是问题就是「如何求所有符合要求的排列数量」(折磨了好久)

这里给出dp[][]数组的定义:

那么「状态转移方程」是什么呢?

那么「base case」是什么呢?

最后的结果就是「第n个位置放置 ➕ 第n个位置不放置」

下面给出完整代码:

其实这个题目和 将字符串翻转到单调递增 有相似之处,有兴趣的可以去看看,这里给出代码:

不同骰子序列的数目

题目详情可见 不同骰子序列的数目

该问题有两个约束条件:

这里给出dp[][][]数组的定义:

那么「状态转移方程」是什么呢?

那么「base case」是什么呢?

最后的结果就是「第n轮倒数两个数的所有排列之和」

下面给出完整代码:

下面再给出一种「记忆化搜索」方法实现的代码:(思路和上面的 DP 差不多)

拼接数组的最大分数

题目详情可见 拼接数组的最大分数

这个题目在比赛中一下就想到了用「前缀和」解决,大概思路:分别求出两个数组的前缀和,然后求出差值最大的子数组之和

这无疑需要使用双重循环遍历所有子数组,最后直接超时!!!

比赛结束后,看到了一句话,醍醐灌顶!!「转化成求最大子数组之和」

以两个数组的差值为目标数组,然后求出该差值数组的最大子数组之和即可,可参考 最大子数组和

下面给出完整代码: