第十六届蓝桥杯省模拟赛第二期第四题dp问题深度剖析

今天,我要分享的是最近参加的蓝桥杯省赛模拟赛的第四题的dp问题的解析,从零基础到基本掌握dp思想,有一定基础的同学可以直接跳到最后看答案的代码和解题思路就行。


🚀1.dp思想

相信大家都听说过状态转移方程,但是很多朋友一直以来很难入门dp的问题就是,状态转移方程是怎么来的?为什么叫状态转移方程?为什么dp问题需要状态转移方程?

🚀2.状态转移方程

状态转移方程的本质:就是通过记录前面的结果的状态,再用前面结果的状态去推出后面结果的状态。

可能大家听到这里好像还是有点迷迷糊糊,没关系,我们来看一道dp的入门题,你就明白了。

🚀3.单状态转移方程

解释是一下这里指的一个状态仅有另一个状态推导出

这里我们通过看这个题目其实不难发现,我们的f(n)的结果是由f(n-1)和f(n-2)两个共同决定的,而如果我们从状态来看,就是f(n)的状态是由f(n-1)+f(n-2)转化过来的。

这里我们就可以列出我们的状态转移方程了

f(n)=f(n-1)+f(n-2)

这下面的做题代码相对简单,小赵就不写了。

🚀4.多状态转移方程

我们前面的问题相对基础,我们大多数在考场上面临的问题,大多都是多状态转移方程。

我们来根据题目去学习这样的多状态的思想。

这道题目的难点就在于,我们每个屋子都有两个状态一个是偷的状态,一个是不偷的状态,那怎么办呢?那就分别记录。用一个数组记录当下这个房子偷的状态的最大金额,用另一个数组记录这个房子不偷的金额。

首先来看偷的状态:

我们偷的状态其实就是要由前面一个房子不偷的最大状态去转移过来,那么我们就可以列出式子

f(n)=g(n-1)+num(n)

然后我们在来看当下这个房子不偷的状态

这里就是由前面两种可能的状态转移过来,一种是偷,一种是不偷,那么我们这里就要选取最大值,也可以列出我们的状态转移方程

g(n)=max(f(n-1),g(n-1))

接着我们在进行一定的初始化工作,然后算出每个位置的值这道题就算结束了。

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {
        int numsize=nums.size();
        if(numsize==1)  return nums[0];
        vector<int> f(numsize);
        vector<int> g(numsize);
        f[0]=nums[0];//初始化
        g[0]=0;
        for(int i=1;i<numsize;i++)//从左向右填表
        {
            f[i]=g[i-1]+nums[i];
            g[i]=max(f[i-1],g[i-1]);
        }
        return max(f[numsize-1],g[numsize-1]);//最后返回最后一个房子偷和不偷两种情况中的较大值
    }
};

🚀 5.蓝桥杯省模拟赛第二期第四题

蓝桥杯的这道题目和我们前面说的题目很像,但又略微有点不同,我们下面看题目就会知道其中的原因。

其实这里和我们之前的题目一样,我们这个数字可能由状态过来。

在考场的时候,我就是这样想的,但是随机又出现了一个问题就是这个最大整数的好像不止这一个情况可以过来。

那如果是这样玩那我们的dp方程就很难解决了,但是如果我们换一种思想就可以轻易解决这个问题,就是我用前一种状态直接推后一种状态(那么这样就是确定的只有三种),然后让他们在推的过程中取最小值。

cpp 复制代码
int max_digit(int n)
{
    int res = 0;
    while (n)
    {
        res = max(res, n % 10);
        n /= 10;
    }
    return res;
}//分离数位,返回最大值
int dp[2029];
int main()
{
	memset(dp, 0x3f3f3f, sizeof(dp));//每个位置都是最大值
	dp[1] = 0;//初始条件
	for (int i = 1; i <= 2050; i++)
	{
		dp[i + 1] = min(dp[i + 1], dp[i] + 1);//代价1
		dp[i + max_digit(i)] = min(dp[i + max_digit(i)], dp[i] + 3);//代价3
		dp[2 * i] = min(dp[2 * i], dp[i] + 10);//代价10
	}
	cout << dp[2024];
	return 0;
}

🚀6.结束语

好了小赵今天的分享就到这里了,如果大家有什么不明白的地方可以在小赵的下方留言哦,同时如果小赵的博客中有什么地方不对也希望得到大家的指点,谢谢各位家人们的支持。你们的支持是小赵创作的动力,加油。

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持小赵,如有不足还请指点,方便小赵及时改正,感谢大家支持!!!

相关推荐
测试者家园30 分钟前
测试用例智能生成:是效率革命,还是“垃圾进,垃圾出”的新挑战?
人工智能·职场和发展·测试用例·测试策略·质量效能·智能化测试·用例设计
win x2 小时前
JavaSE(基础)高频面试点及 知识点
java·面试·职场和发展
橘颂TA5 小时前
【剑斩OFFER】算法的暴力美学——力扣 207 题:课程表
数据结构·c++·算法·leetcode·职场和发展
谁刺我心5 小时前
【蓝桥杯刷题环境】VScode插件算法刷题Competitive Companion
职场和发展·蓝桥杯
有一个好名字6 小时前
力扣-迷宫中离入口最近的出口
算法·leetcode·职场和发展
努力学算法的蒟蒻6 小时前
day72(1.31)——leetcode面试经典150
面试·职场和发展
YuTaoShao7 小时前
【LeetCode 每日一题】744. 寻找比目标字母大的最小字母——(解法一)遍历
算法·leetcode·职场和发展
南风知我意95720 小时前
【前端面试2】基础面试(杂项)
前端·面试·职场和发展
YuTaoShao1 天前
【LeetCode 每日一题】2976. 转换字符串的最小成本 I
算法·leetcode·职场和发展
码农水水1 天前
得物Java面试被问:消息队列的死信队列和重试机制
java·开发语言·jvm·数据结构·机器学习·面试·职场和发展