动态规划入门(一)

什么是动态规划?
动态规划是分阶段划分求最优值的的算法。
1将复杂问题按阶段划分成子问题;
2枚举问题各种可能情况,从中找出最优值;
3利用子问题的最优解球的原问题的最优解。
列1
小明写了一个简单的吃金币游戏,规则如下:
在一个长方形地图上,玩家每次能从一个方格走到相邻一个方格。
玩家控制的角色可以向下或者向右走,但不能向上或向左走。每个方格上都有
一定的金币。
现在,小明想请你帮他想一个策略,尽可能多的获得金币(从左上角走到右下角可能获得的最大金币数)。

如果用F[a][b]表示达到(a,b)这个点时所能吃到的最大金币数量。
得到 递推关系式:
F[a][b]=max(F[a-1][b],F[a][b-1])+Coin[a][b]//状态转移方程
(此步即为递归定义最优解的值,列出状态转移方程)
F[m][n]即为所求。
那么为什么是这样那?
思路如下;
我们每次只能向下或向右走一步,并且最后我们一定在右下角。那么我们把这个方格看作一个二位数组。那么最后的一个空格的来路只有两种情况。即当前位置F[a][b]=max(F[a-1][b],F[a][b-1])+Coin[a][b](从上或从左中的最大值加上当前位置的金币。
代码如下:


```cpp
#include<iostream>
using namespace std;
int f[MAX][MAX];
int main()
{
int c,m,n;
cin>>m>>n;
for(int i=1;i<=m;i++)
	for(int j=1;j<=n;j++)

	{
		cin>>c;

		f[i][j]=max(f[i][j-1],f[i-1][j])+c;//状态转移方程,上一步的最优解和本步
	
     } 
     cout<<f[m][n];
     return 0;
}`

动态规划问题具有以下基本特征:
1问题具有多阶段决策的特征。
2每一阶段都有相对应的状态与之的对应,描述状态的量称为状态变量。
3每一阶段都面临体格决策,选着不同的决策将会导致下一阶段不同的
状台。
4每一阶段的最优解问题可以递归地归结为下一阶段各个状态的最优解问题,个子问题与原问题具有完全相同的结构。
动态规划一般步骤
1判断问题是否具有最优子结构,若不具有则不用动态规划。
2分解成若干个子问题。
3递推公式。
4找出边界条件。
5已知边界值带入方程。
列2
最长上升子序列。
给出一个数列{a1,a2,…,an},要求你选出尽量多的元素,使这些元素按其相对位置单调递增。

任务就是对于给定的序列,求出最长上升子序列的长度。

输入数据:输入的第一行是序列的长度N(1<=N<=1000)。第二行给出序列中的N个整数,这些整数的取值范围都是0~10000。

输出要求:最长上升子序列的长度。

输入样例:

7

1 7 3 5 9 4 8

输出样例:

4
方法:分解子问题,求以ak(k=1,2,3’’’’’)为最长上升子序列的长度为子问题。

在这里插入图片描述`在这里插入代码片
#include
#include
using namespace std;
#define MAX_N 1000
int b[MAX_N+10];
int maxLen[MAX_N+10];

int main()
{
int N;
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&b[i]);
maxLen[1]=1;
for(int i=2;i<=N;i++)
//每次求以第i个数为终点的最长上升子序列的长度
{
int temp=0; //记录满足条件的,第i个数左边的上升子序列的最大长度
for(int j=1;j<i;j++)
{//查看以第j个数为终点的最长上升子序列
if(b[i]>b[j])
{
if(temp<maxLen[j])
temp=maxLen[j];
}
}
maxLen[i]=temp+1;
}
int maxL=-1;
for(int i=1;i<=N;i++)
if(maxL<maxLen[i])
maxL=maxLen[i];
printf("%d\n",maxL);
return 0;

}
列3
最长公共子序列
在序列X={x1,x2,…,xm}与Y={y1,y2,…,yn}中查找长度最长的公共子序列,往往不是一个。例如:X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A},则公共子序列有Z={B,C,B,A},Z1={B,D,A,B},Z2={B,C,A,B}

分析:
用c[i][j]记录序列Xi和Yi的最长公共子序列的长度。当i=0或者j=0时,Xi和Yi的最长公共子序列为空,所以c[i][j]=0。
其他情况:当xi=yi时,c[i][j]=c[i-1][j-1]+1。当xi不等于yi时,c[i][j]=max{c[i][j-1],c[i-1][j]}

`

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聆听我的召唤,菜鸟进化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值