目录
一、作业1爬楼梯
二、作业二机器人走格子
三、机器人走有障碍的格子
四、投掷头子的N种方法
五、编辑距离
% 作业1:爬楼梯
% 题目来源:力扣70. 爬楼梯 链接:https://leetcode-cn.com/problems/climbing-stairs
function F = homework1(n)
if n == 1
F = 1;
elseif n == 2
F = 2;
else
FF = ones(1,n); % 初始化DP数组
FF(2) = 2;
for i = 3:n
FF(i) = FF(i-1) + FF(i-2);
end
F = FF(n);
end
end
% 作业2:机器人走格子
% 题目来源:力扣62. 不同路径 链接:https://leetcode-cn.com/problems/unique-paths/
function f = homework2(m,n)
% 格子有m行n列
FF = ones(m,n); % 初始化DP数组全为1
% 循环计算右下部分的元素
for i = 2:m
for j = 2:n
tem1 = FF(i,j-1); % 左侧过来
tem2 = FF(i-1,j); % 上面过来
FF(i,j) = tem1+tem2;
end
end
f = FF(m,n);
end
% 作业3:机器人走有障碍的格子
% 题目来源:力扣63. 不同路径 II 链接:https://leetcode-cn.com/problems/unique-paths-ii/
function f = homework3(obstacle)
% obstacle是障碍物矩阵,全为0和1组成,1表示有障碍物
[m,n] = size(obstacle);
FF = ones(m,n); % 初始化DP数组
% 处理第一列
for i = 1:m
if obstacle(i,1) == 1 % 发现了障碍物
FF(i:end,1) = 0; % 障碍物所处的位置以及下方的位置对应的f(i,j)=0
break
end
end
% 处理第一行
for j = 1:n
if obstacle(1,j) == 1
FF(1,j:end) = 0; % 障碍物所处的位置以及右边的位置对应的f(i,j)=0
break
end
end
% 循环计算右下部分的元素
for i = 2:m
for j = 2:n
if obstacle(i,j) == 1
FF(i,j) = 0;
else
FF(i,j) = FF(i,j-1)+FF(i-1,j);
end
end
end
f = FF(m,n);
end
% 作业4:掷骰子的N种方法
% 题目来源:力扣1155. 掷骰子的N种方法 链接:https://leetcode-cn.com/problems/number-of-dice-rolls-with-target-sum
function f = homework4(m, f, S)
% m个骰子,每个骰子f个面,需要掷出总点数为S
FF = zeros(m,S); % 初始化DP数组
% 处理第一列
FF(1,1) = 1; % 第一个元素为1,其余位置元素为0.
% 处理第一行
for j = 1:S
if j <= f
FF(1,j) = 1; % 前f个元素(如果有的话)为1,其余位置元素为0.
end
end
% 循环计算右下部分的元素
for i = 2:m
for j = 2:S
for k = 1:f
if j > k
FF(i,j) = FF(i,j)+FF(i-1,j-k);
else
break
end
end
end
end
f = FF(m,S);
end
作业5参考答案:
% 作业5:编辑距离
% 题目来源:力扣72. 编辑距离 链接:https://leetcode-cn.com/problems/edit-distance/
function f = homework5(word1,word2)
m = length(word1);
n = length(word2);
FF = ones(m,n); % 初始化DP数组
% 处理第一行
ind = strfind(word2, word1(1)); % 在word2中找word1的第一个字母
for j = 1:n
if isempty(ind) % word1的第1个字母不在word2中
FF(1,j)=j;
% word1的第一个字母在word2中时, ind里面可能有多个位置,我们只需要首次出现的位置
elseif ind(1)==1 % word1和word2的第1个字母相同
FF(1,j)=j-1;
else
% 如果位置不为1,那么该位置之前的FF(1,j)=j,该位置以及该位置之后的FF(1,j)=j-1
if j < ind(1)
FF(1,j)=j;
else
FF(1,j)=j-1;
end
end
end
% 处理第一列
ind = strfind(word1, word2(1)); % 在word1中找word2的第一个字母
for i = 1:m
if isempty(ind) % word2的第1个字母不在word1中
FF(i,1)=i;
% word2的第一个字母在word1中时, ind里面可能有多个位置,我们只需要首次出现的位置
elseif ind(1)==1 % word1和word2的第1个字母相同
FF(i,1)=i-1;
else
% 如果位置不为1,那么该位置之前的FF(i,1)=i,该位置以及该位置之后的FF(i,1)=i-1
if i < ind(1)
FF(i,1)=i;
else
FF(i,1)=i-1;
end
end
end
% 循环计算右下部分的元素
for i = 2:m
for j = 2:n
tmp1 = FF(i-1,j-1) + (word1(i) ~= word2(j))*1;
% 先把 word1[1..i-1] 变换到 word2[1..j-1],消耗掉FF(i-1,j-1)步,
% 再把 word1[i] 改成 word2[j],就行了。
% 这里分为两种情况:如果 word1[i] == word2[j],什么也不用做,一共消耗 FF(i-1,j-1) 步;
% 否则需要替换最后一个字符,一共消耗 FF(i-1,j-1) + 1 步。
tmp2 = FF(i-1,j) + 1;
% 先把 word1[1..i-1] 变换到 word2[1..j],消耗掉 FF(i-1,j) 步,
% 再把 word1[i] 删除,这样word1[1..i] 就完全变成了 word2[1..j] 了,
% 一共消耗FF(i-1,j)+ 1 步。
tmp3 = FF(i,j-1) + 1;
% 先把 word1[1..i] 变换成 word2[1..j-1],消耗掉 FF(i,j-1) 步
% 接下来,再插入一个字符 word2[j], word1[1..i] 就完全变成了 word2[1..j] 了。
% 一共消耗FF(i,j-1)+ 1 步。
FF(i,j) = min([tmp1,tmp2,tmp3]);
% 从上面三个问题来看,word1[1..i] 变换成 word2[1..j] 主要有三种操作
% 哪种操作步数最少就用哪种。
end
end
f =FF(m,n);
end
参考资料:数学建模清风:动态规划课程 https://www.bilibili.com/video/BV1tp4y167c5