动态规划-最短路径

斐波那契数列:
分治法(自顶向下):web

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点到终点的距离,经过层层递归求出每一个点到终点的距离。svg

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的重复计算,具备最优子结构性质,能够运用动态规划
代码以下:ui

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];
}