斐波那契数列:
分治法(自顶向下):
int fb(int n)
{
if(n==1||n==2)
return 1;
else
return fb(n-1)+fb(n-2);
}
可以看出每次进入else就进入两个递归式,则会重复计算多次f(1)与f(2)。
动态规划算法(自底向上):
int fb(int n,map<int,int>&m)//运用map为按键—值对存取,与顺序无关,可以用来存取fb(n-1)与fb(n-2)的数,无需再进行递归求值,减少重复计算量
{
if(n==1||n==2)
return 1;
else
{
auto itr=m.find(n);//查找n是否在map中,find(成功返回itr指向存储n的地址,否则返回end())
if(itr==m.end())//序号为n的键不在map中
{
int temp=fb(n-1,m)+fb(n-2,m);//求值
m.insert(n,temp);//存值,方便读值
}
else
{
return itr->second;
}
}
}
有向图,最短路径算法:
用二维数组存放每个点到终点的距离
运用动态规划思想,通过求min(v)={m(v,u)+min(u)}
含义为:求v到终点的距离转换成,v点到u点的距离加上u点到终点的距离,通过层层递归求出每个点到终点的距离。
int Min(int n)
{
if(n==len)//len为点的个数
return 0;
int min=-1,t=0,flag;
for(int i=n+1;i<l;i++)
{
if(m[n][i]==0)
continue;
t=m[n][i]+Min(i);
if(t>min)
{
min=t;
flag=i;
}
}
trace[n]=flag;//跟踪到最短路径的点
return min;
}
上图求A到E距离,运用Min算法运算,算法会计算min=A1-B1-C1-D1-E,然后计算t=A1-B1-C2-D1-E,其中D1-E的重复计算,具有最优子结构性质,可以运用动态规划
代码如下:
int Min(int n)
{
if(minary[n]!=0)//minary[]为存放每个点到终点距离,可以防止重复计算
return minary[n];
if(n==len)//len为点的个数
return 0;
int min=-1,t=0,flag;
for(int i=n+1;i<l;i++)
{
if(m[n][i]==0)
continue;
t=m[n][i]+Min(i);
if(t>min)
{
min=t;
flag=i;
}
}
trace[n]=flag;//跟踪到最短路径的点
minary[n]=min;
return minary[n];
}