(思考)我们知道贪婪算法也是进行多阶段的决策过程,通过一系列的贪婪决策找到最优解.那么动态规划和贪婪算法的区别在哪里?
如果不太清楚,我们从今天这个列子来体会.
数塔问题:
数塔从顶部出发,在每一个节点可以选择向左走或是向右走,一直走到底层,要去找出一条路径,
使路径上的数值和最大.
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16
算法策略:
这个问题不能用贪婪法来解决,为什么呢?
因为贪婪策略每次无论是向上而下,还是自下而上,每次向下都选择较大的一个数移动.
但是由于我们采用贪婪策略,无法得到数塔的全貌只是在一层做贪婪选择,这样可能会得到不正确的答案,所以不采用.
若采用枚举算法?
在数塔的层数为n时,要枚举的路径为2^n-1,数目非常之大,所以也不采用.
分而治之的算法呢?
这个问题的原始数据是一个三角形的二维图形,而且问题的答案与各层数据间关系复杂,所以不适合采用分治法.
所以采用动态规划.
分析一下动态规划的过程:
1)数据结构采用:
原始数据采用二维数组来模拟数塔.
2)动态规划的过程存储:
如果仅仅是求最优解,那么采用一维数组存储最新的决策过程即可,但是这块要求经过的路径,那么采用另一个二维数组存储最新决策.
3)最优解路径求解及存储
原始数据data: 最优解求解策略数组d(由底向上)
9 59
12 15 50 49
10 6 8 38 34 29
2 18 9 5 21 28 19 21
19 7 10 4 16 19 7 10 4 16
计算路径的过程:
1.输出data[0][0]=9
2.d[0][0]-data[0][0]=50 对应d[1][0]----->输出data[1][0]=12
3.d[1][0]-data[1][0]=38 对应d[2][0]----->输出data[2][0]=10
4.d[2][0]-data[2][0]=28 对应d[3][1]----->输出data[3][1]=18
5.d[3][1]-data[3][1]=10 对应d[4][3]----->输出data[4][3]=10
过程想清楚之后也就好写代码了.
代码实现:(以题目中的五层为列)
#include
#include
#include
using namespace std;
int getmax(int a, int b)
{
return (a > b) ? a : b;
}
vector GetMaxroad(int data[10][10],int maxlayer, int *max)
{
vector v;
int i, j;
int d[10][10];
//初始化数组d
for (i = 0; i < maxlayer; ++i)
{
for (j = 0; j <= i; ++j)
{
d[i][j] = data[i][j];
}
}
//进行动态规划,计算出最优解
for (i = maxlayer - 2; i >= 0;--i)
{
for (j = 0; j <= i; ++j)
{
d[i][j] += getmax(d[i+1][j],d[i+1][j+1]);
}
}
*max = d[0][0];
int max1 = d[0][0];
//根据最优解的策略,计算出最优路径
for (i = 0; i < maxlayer; ++i)
{
for (j = 0; j <= i; ++j)
{
if (max1 == d[i][j])
{
v.push_back(data[i][j]);
max1 = max1 - data[i][j];
continue;
}
}
}
return v;
}
int main()
{
int data[10][10];//用二维数组模拟数塔
vector result;//得到路径
int max=0;
int n;//层数
cin >> n;
//初始化数塔
for (int i = 0; i < n; ++i)
{
for (int j = 0; j <= i; ++j)
{
cin >> data[i][j];
}
}
result = GetMaxroad(data,n,&max);
cout << "最优解是" << max << endl;
cout << "路径为:";
for (int i = 0; i < result.size(); ++i)
{
cout << result[i]<<" ";
}
cout << endl;
return 0;
}
现在应该可以稍微体会到了动态规划和贪婪算法的区别了.
我来回答这个问题:
贪婪算法的效率比较高,每次作出的决策都是局部的,唯一的.且贪婪算法是在"线性的解决问题",所以贪婪算法适用问题的范围小.
而动态规划的每个阶段的决策,作出的是一组局部的决策结果,每一个阶段都使问题规模变小,且更加接近最优解,直到最后一步,问题的规模变为1,就找到了问题的解.所以动态规划是全面分阶段的解决问题.