动态规划算法理解——从例题中学习

本文通过四个逐步增加难度的题目,详细解析动态规划算法的应用。从牛妹的蛋糕问题到复杂的跑步路线规划,每个问题都包含思路分析和状态转移方程,帮助读者深入理解动态规划解决问题的技巧。
摘要由CSDN通过智能技术生成

这些题目的难度是递增顺序来的,后续慢慢再补

第一题(牛妹的蛋糕)

题目描述

众所周知,牛妹非常喜欢吃蛋糕。
第一天牛妹吃掉蛋糕总数三分之一(向下取整)多一个,第二天又将剩下的蛋糕吃掉三分之一(向下取整)多一个,以后每天吃掉前一天剩下的三分之一(向下取整)多一个,到第n天准备吃的时候只剩下一个蛋糕。
牛妹想知道第一天开始吃的时候蛋糕一共有多少呢?

示例1
输入
复制
2
返回值
复制
3

思路:

1.(数学分析)首先假设第一天准备开始吃的时候有x份蛋糕,那么第二天准备开始吃的时候的蛋糕 x-(x*1/3 + 1) = x * 2/3 - 1 份蛋糕。
2.(找状态方程)设dp[i]为第i天准备开始吃的时候有dp[i]份蛋糕,那么第二天准备开始吃的时候的蛋糕就为dp[i+1];根据1的分析可得 dp[i+1] = dp[i] * 2/3 - 1;
3.因为题目给定的n代表的是,最后一天她正准备吃的时候剩下的数量,我们要根据这个数量往前推出她第一天的蛋糕数。所以可得方程式dp[i] = 3 * (dp[i+1]+1) / 2; (就是2中的方程变形)。

完事写代码
#include<iostream>
using namespace std;

 int cakeNumber(int n) {
   
    int dp = 1;
    for(int i = n - 1; i >= 1; --i)
    {
   
        dp = 3 * (dp + 1) / 2;
    }
	return dp;
}
int main()
{
   
	int n;
	cin >> n;
	cout << cakeNumber(n);
	return 0;	
} 

第二题(牛妹的礼物)

题目描述
众所周知,牛妹有很多很多粉丝,粉丝送了很多很多礼物给牛妹,牛妹的礼物摆满了地板。
地板是N\times MN×M的格子,每个格子有且只有一个礼物,牛妹已知每个礼物的体积。
地板的坐标是左上角(1,1) 右下角(N, M)。
牛妹只想要从屋子左上角走到右下角,每次走一步,每步只能向下走一步或者向右走一步或者向右下走一步
每次走过一个格子,拿起(并且必须拿上)这个格子上的礼物。
牛妹想知道,她能走到最后拿起的所有礼物体积最小和是多少?

思路

首先把题目给定的礼物体积存入一个二维数组A[MAX][MAX]中,然后准备开始动态规划了。设一个二维数组dp[MAX][MAX],先初始化计算它的第一行第一列,因为第一行第一列的所有数据只能是通过它的前一个数据得来,初始完之后,计算其他的。
状态方程 :dp[i][j] = min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j])) + A[i][j];
就是判断当前点的向上一个数据,向左的一个数据,左上的一个数据,这三个数据的最小值再加上当前的体积值就是该点的值。

完事写代码
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define MAX 1100
int dp[MAX][MAX],A[MAX][MAX];

int main()
{
   
	int m,n;
	cin >> n >> m;
	for(int i = 1; i <= n; ++i){
   
		for(int j = 1; j <= m; ++j){
   
			cin >> 	A[i][j];	
			dp[i][j] = 0; 
		}		
	}	
	dp[1][1] = A[1][1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值