# 【算法】详解动态规划

首先学习动态规划，我们的先知道什么是动态规划？

动态规划的应用场景：

我们解决动态规划问题一般分为四步：
1、定义一个状态，这是一个最优解的结构特征
2、进行状态递推，得到递推公式
3、进行初始化
4、返回结果

[编程题]斐波那契数列

n<=39

class Solution {
public:
int Fibonacci(int n) {
if(n<=0)
return 0;
if(n == 1 || n == 2)
return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
};

class Solution {
public:

int Fibonacci(int n) {
//先申请一个空间来保存解
vector<int> f(n + 1, 0);
//初始化
f[0] = 0;

if (n <= 0)
return f[0];
f[1] = 1;
if (n == 1)
return f[1];
f[2] = 1;
//状态递推
for (int i = 3; i <= n; i++)
{
f[i] = f[i - 1] + f[i - 2];
}
//返回结果
return f[n];
}
};

class Solution {
public:

int Fibonacci(int n) {
if (n <= 0)
return 0;
if(n == 1 || n == 2)
return 1;
//初始化
int fn1 = 0;
int fn2 = 1;
int resault = 0;
for (int i = 2; i <= n; i++)
{
//递推公式
resault = fn1 + fn2;
fn1 = fn2;
fn2 = resault;
}
//返回结果
return resault;
}
};

[编程题]变态跳台阶

class Solution {
public:
int jumpFloorII(int number) {
if (number <= 0)
return 0;
//初始化
int total = 1;
for (int i = 1; i < number; i++)
{
//递推
total = 2 * total;
}
//返回结果
}
};

[编程题]矩形覆盖

class Solution {
public:
int rectCover(int number) {
if (number <= 0)
return 0;
if (number == 1)
return 1;
if (number == 2)
return 2;
vector<int> f(number + 1, 0);
//初始化
f[0] = 0;
f[1] = 1;
f[2] = 2;
for (int i = 3; i <= number; i++)
{
//状态递推
f[i] = f[i - 1] + f[i - 2];
}
//返回结果
return f[number];
}
};

[编程题]最大连续数列和

[1,2,3,-6,1]

class MaxSum {
public:
int getMaxSum(vector<int> A, int n) {
// write code here
if (A.empty())
return 0;
vector<int> f(A.size(), 0);
//初始化
f[0] = A[0];
for (int i = 1; i < A.size(); i++)
{
//状态递推
f[i] = max(f[i - 1] + A[i], A[i]);
}
//输出结果
int resault = A[0];
for (int i = 0; i < A.size(); i++)
{
resault = max(f[i], resault);
}
return resault;
}
};

[编程题]word-break

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s =”leetcode”,
dict =[“leet”, “code”].

Return true because”leetcode”can be segmented as”leet code”.

s =”leetcode”,
dict =[“leet”, “code”].

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
if (s.empty() || dict.empty())
return false;
int n = s.size();
vector<bool> can_break(n + 1, false);
//初始化
can_break[0] = true;
//递推
for (int i = 1; i <= n; i++)
for (int j = 0; j < i; j++)
{
if (can_break[j] && dict.find(s.substr(j,i-j)) != dict.end())
{
can_break[i] = true;
break;
}
}
return can_break[n];
}
};

[编程题]triangle

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]

The minimum path sum from top to bottom is11(i.e., 2 + 3 + 5 + 1 = 11).

Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

[
〔2〕；
[3,4]，
[6]，[5]，[7]
[41,1,3]
]

class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
if (triangle.empty())
return 0;
vector<vector<int>>  min_sum(triangle);
//初始化
min_sum[0][0] = triangle[0][0];
//递推
for (int i = 1; i < triangle.size(); i++)
{
for (int j = 0; j <= i; j++)
{
//左边界
if (j == 0)
{
min_sum[i][j] = min_sum[i - 1][j] + triangle[i][j];
}
//右边界
else if (j == i)
{
min_sum[i][j] = min_sum[i - 1][j - 1] + triangle[i][j];
}
//中间
else
{
min_sum[i][j] = min(min_sum[i - 1][j - 1], min_sum[i - 1][j]);
min_sum[i][j] = min_sum[i][j] + triangle[i][j];
}
}
}
int line = triangle.size();
int resault = min_sum[line - 1][0];
for (int i = 1; i < line; i++)
{
resault = min(resault, min_sum[line - 1][i]);
}
//返回结果
return resault;
}
};

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客