DP动态规划-打ACM你必须知道的算法

Posted Ja_king_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DP动态规划-打ACM你必须知道的算法相关的知识,希望对你有一定的参考价值。

动态规划

1.什么是动态规划?
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。解决DP问题,要明确转移和状态两个问题。
这么说大家可能也不知道啥是动态规划,那我们一起看看一些经典例题吧!

2.经典例题1:数字三角形
(1)给你一个数字三角形,从顶点出发,向下或向右下走一步,直至最底层,将途经相加,所得到的最大值。
在这里插入图片描述
如上图所示,7开始,可以选择向下或向右下走一步。能得到的最大值便是30。
(2)这题如何解决呢?
定义f[i][j]表示从(1,1)出发走到(i,j)所有路径的最大和。
7
3 8
8 1 0
例如:f[3][2]=max{7+3+1,7+8+1}=16(因为到达(3,2)这点就两条路径)
所以我们便可以直接DP,最后在max(f[n][1]…f[n][n])中找答案即可。
在这里插入图片描述
大致过程如图所示。

3.经典例题2:最长上升子序列
(1)题目描述:给你一个数组,删除部分元素得到最长上升子序列
如:1 13 5 7 8 2 11
5
1 5 7 8 11
(2)这题如何解决呢?
f[i]表示以i结尾的上升子序列中的最长长度。
f[j]=max(f[i])+1,a[i]<a[j]
在这里插入图片描述
大致如图所示。

读到这里,你是不是觉得很简单,那我们来看看一道比较有难度的题吧

4.经典题目3:过河卒问题
在这里插入图片描述
这题看起来是不是有点难度啦?
其实也非常简单,马拦截的地方赋值为0,然后DP,a[i][j]=a[i-1][j]+a[i][j-1]
我们来看看代码实现吧:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int x1[9]={0,-2,-1,1,2,2,1,-1,-2};
const int y1[9]={0,1,2,2,1,-1,-2,-2,-1};
long long s[25][25]={0},a[25][25]={0};
int n,m,x,y;

int main()
{
	scanf("%d%d%d%d",&n,&m,&x,&y);
	memset(a,0,sizeof(a));
	a[x][y]=1;
	for(int i=1;i<=8;i++)
	 if(x+x1[i]>=0&&y+y1[i]>=0) 
	   a[x+x1[i]][y+y1[i]]=1;
	//a数组用来标记马的位置,马和马的控制点设为1
	
    s[0][0]=1;
    for(int i=1;i<=n;i++) 
    {
    	if(a[i][0]==0) s[i][0]=1;
    	else break;//如果边界有马,后面的就都为0
    } //行
     for(int j=1;j<=m;j++) 
     {
     	if(a[0][j]==0) s[0][j]=1;
     	else break;
     } //列
     //设置边界的初值
     
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
     {
     	if(a[i][j]==0) 
     	  s[i][j]=s[i-1][j]+s[i][j-1];
     	 //位置没有马就继续累加
     	else s[i][j]=0;
     }
    printf("%I64d",s[n][m]);
	return 0;
}

这样就过了,这是洛谷的一道题,大家可以去做做哟~

5.这些你都懂了,那就做做01背包问题吧
在这里插入图片描述
这也是DP经典问题,大家尝试做做看!

关注我,下期我们来分析01背包问题!!!

以上是关于DP动态规划-打ACM你必须知道的算法的主要内容,如果未能解决你的问题,请参考以下文章

(转)dp动态规划分类详解

动态规划算法(Dynamic Programming,简称 DP)

dp动归总结

北大学霸总结的动态规划4步曲,仅这篇动归够了

0x53. 动态规划 - 区间DP(习题详解 × 8)

DP 动态规划算法 (Python3)