何为动态规划

原篇:看一遍就理解:动态规划详解 - 知乎

  • 什么是动态规划?
  • 动态规划的核心思想
  • 动态规划的解题套路
  • 一个例子走进动态规划

什么是动态规划?

动态规划(英语:Dynamic programming,简称 DP),通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法(类似于递推)。

动态规划核心思想

动态规划最核心的思想,就在于拆分子问题,记住过往,减少重复计算

动态规划的解题套路

什么样的问题可以考虑使用动态规划解决呢?

★ 如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。
 

比如一些求最值的场景,如最长递增子序列、最小编辑距离、背包问题、凑零钱问题等等,都是动态规划的经典应用场景。

动态规划的解题思路

动态规划的核心思想就是拆分子问题,记住过往,减少重复计算。 并且动态规划一般都是自底向上的,因此我总结了一下我做动态规划的思路:

  • 穷举分析
  • 确定边界
  • 找出规律,确定最优子结构
  • 写出状态转移方程

例如:最长上升子序列

题目描述

这是一个简单的动规板子题。

给出一个由n(n≤5000) 个不超过 10^6 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。

最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。

输入格式

第一行,一个整数 n,表示序列长度。

第二行有 n 个整数,表示这个序列。

输出格式

一个整数表示答案。

输入 #1复制

6
1 2 4 1 3 4

输出 #1复制

4

1.穷举分析

寻找数组a[i]的最长递增子序列长度跟什么有关系,显然a【i】的长度与比i下标小的数有关。我们用dp数组存放最长递增子序列长度,由案例分析,当n=1时,数组只有1,那么dp【1】=1,当n=2时,数组为1 2,那么dp【2】=2,当n=3时,dp【3】=3,当n=4时,dp【4】=1,当n=5时,dp【5】=3,当n=6时,dp【6】=4。

分析找规律,拆分子问题

通过上面分析,我们可以发现一个规律:如果新加入一个元素a[i],最长递增子序列要么是以a[i]结尾的递增子序列,要么就是a[j]的最长递增子序列在加上元素a【i】(即加1),其中j就是下标比i小的下标,并且a【j】也要比a【i】小。

最简单的边界情况

当a数组只有一个元素时,最长递增子序列的长度dp(1)=1,当a数组有两个元素时,dp(2) =2或者1, 因此边界就是dp(1)=1。

确定最优子结构

从穷举分析,我们可以得出,以下的最优结构:

dp(i) =max(dp(j))+1,存在j属于区间[0,i-1],并且num[i]>num[j]。

max(dp(j)) 就是最优子结构。

状态转移方程

数组a[i]的最长递增子序列就是:

最长递增子序列 =max(dp[i])

 实现代码:

#include<bits/stdc++.h>
using namespace std;
int a[5010],dp[5010],maxn=0;
int main(){
	ios::sync_with_stdio(false);
	int n;
	cin >> n;
	for(int i=1;i<=n;++i)
	{
	  cin >> a[i];
	}
    for(int i=1;i<=n;++i)
	{
	  dp[i]=1;//边界都为1
	  for(int j=1;j<i;++j){//j必须比i小
	  	if(a[j]<a[i]){//当a【j】比a【i】小时,dp【i】最大递增子序列就是dp【j】+1
	  		dp[i]=max(dp[i],dp[j]+1);//比a【i】小的数有多个,我们只要最大的序列,因此需要用max函数和自身比较,求出最大子序列
		  }
		  maxn=max(maxn,dp[i]);//另开一个变量存储最大子序列长度
	  }
	}
	cout << maxn << endl;
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值