动态规划

来源:互联网 发布:中国水污染地图数据库 编辑:程序博客网 时间:2024/06/03 21:32

动态规划

7-30,我们学习了一个比较重要的知识——动态规划。

动态规划,从字面上理解就是动态地取规划某件事情,使其得到最优结果。规划之中就会有选择到底要还是不要,做还是不做,所以动态规划就是要选择最优。

动态规划有4个核心:阶段、最优、子问题和边界。在分析动态规划这种问题时只要找出这4个核心,那变成解决问题起来就比较简单了。

下面就通过一道题目来了解一下4个核心分别什么以及如何找出这4个核心吧

1. 抢金块(gold

问题描述

地面上有一些格子,每个格子上面都有金块,但不同格子上的金块有不同的价值,你一次可以跳ST (2ST10) 如果S=2T=4。你就可以跳2步、3步或4步,告诉你这些后,你从第一个格子起跳,必须跳到最后一个格子上,请你输出最多可以获得的金块的总价值。

输入格式

第一行是格子个数;

第二行是ST ,保证T大于S

第三行是每个格子上的金块价值。第一个为第一个格子上的价值,默认从第一个格子起跳,必须跳到最后一个格子上,也就是说第一个格子上的金块和最后一个格子的金块你就可以直接获得了。

输出格式

 输出最多可以获得的金块的总价值。

输入样例

10

2 3

4 5 8 2 8 3 6 7 2 9

输出样例

36

样例说明:

135810

总价值:4+8+8+7+9=36

数据规模

格子数目<1000

2≤ST≤10

每个金块的价值<10000

 

这个就是一个经典的动态规划。

先画个图来分析一下。

动态规划 - 周正华 - 周正华的博客

 

上面这幅图就是题目的样例。我们可以看到,按照样例来说:第4个格子就只能由它前面的第23个格子来改变。也就是说,到1号格和2号格的值会决定到4号格的最大值,从开头到前面那两个的两个最大值之中再取一个最大值,然后再加上4号格本身的值,就是从开头一直跳到4号格的最大值。

写成动态转移方程就是:f[i]=max(f[i-2],f[i-3])+a[i]

但是要注意的是,这只是样例的ST。因为它要求跳ST格,所以应该是i号格前面的ST格中的最大值加a[i]

好了,分析完问题,那就看回我们那4个核心。

    阶段:每跳一步就是一个阶段;

    最优:这题要求求最大值,这个最大值就是最优。

    子问题:子问题就是每取出一个数,这个数的最大值就等于前面每个能到它的数的最大值中的最大值加上自己本身。

    边界:这题要注意的是:可能从1开始时,执行f[i-2]时,可能会因为没f[-1]而爆掉。

下面是程序:

#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("gold.in");
ofstream fout("gold.out");
#define cin fin
#define cout fout

int n;
int g[1001];
int f[1001];
int oo=100000005;
int s,t;
int ans=0;
int Max=-oo;

int main()
{
cin>>n;
cin>>s>>t;
for(int i=1;i<=n;i++)
cin>>g[i];
for(int i=2;i<=s;i++)
f[i]=-oo;
f[1]=g[1];
for(int i=s+1;i<=n;i++)
{
for(int j=i-t;j<=i-s;j++)
if(Max<f[j]) Max=f[j];
f[i]=Max+g[i];
Max=-oo;
}

cout<<f[n]<<endl;

return 0;
}

其实动态规划还学了01背包和完全背包,下次再上博客。

 

2 0
原创粉丝点击