动态规划-最低通行费

动态规划

我认为动态规划其实就是总问题的最优解依赖于其子问题的最优解,给出初始的最小子问题的答案后就可以一层一层的得出总问题的解。

作业题目的状态转移方程:

1 dp[i] = max(dp[j]+1, dp[i]);

2 if(dp[i][k]+dp[k][j]<dp[i][j])dp[i][j]=dp[i][k]+dp[k][j];

结伴编程

在实验课的结伴编程中,我和队友一起做题,讨论,对动态规划算法有了更深的理解

 

------------------------------------------------------------------------------------(算法第三章作业)--------------------------------------------------------------------------------

 

一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。

这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?

注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。

输入格式:

第一行是一个整数,表示正方形的宽度N (1≤N<100);

后面N行,每行N个不大于100的整数,为网格上每个小方格的费用。

输出格式:

至少需要的费用。

输入样例:

5
1  4  6  8  10 
2  5  7  15 17 
6  8  9  18 20 
10 11 12 19 21 
20 23 25 29 33

输出样例:

109

样例中,最小值为109=1+2+5+7+9+12+19+21+33。

 

商人必须在(2N-1)个单位时间穿越出去

而正方形网格边长为N,商人初始位置在左上角

则商人只能往右或者往下走

 

我们可以认为商人达到某个位置时立刻交费(题目是经过,不过没影响),当商人到某一位置时,所用的最小费用为该位置的费用加上该位置的左边和上边中费用较小的一边,如果在边界(第一行或第一列)则直接取(左边或上边),不用比较

定义二维数组a[i][j]表示到位置第i行第j列,a[i][j]初始值为到达该位置时交的费用,程序执行完毕后a[i][j]为到达该位置的最小费用(从开始点到该位置的路径上所有的费用)

则一般情况:a[i][j]=a[i][j]+min(a[i-1][j],a[i][j-1])

第一行:a[i][j]=a[i][j]+a[i][j-1]

第一列:a[i][j]=a[i][j]+a[i-1][j]

 

这里我按从左往右从上往下的顺序计算,每次计算完当前行时上一行就失去作用了,因为计算完当前行后便计算下一行,而当前行的上一行与当前行的下一行之间隔了一行,每个位置的计算只需要其左边和上边,所以我只用了一维数组,每次计算都是当前行替代上一行

这里数组a是临时存储当前行的每个位置的费用,数组b是到达当前行的每个位置的最小费用

 

#in0clude<iostream>
using namespace std;
int main()
{
    int a[100],b[100],n,i,j;
    while(cin>>n)
    {
        cin>>b[0];
        for(i=1;i<n;i++)
        {
            cin>>b[i];
            b[i]+=b[i-1];
        }
        for(i=1;i<n;i++)
        {
            for(j=0;j<n;j++)
                cin>>a[j];
            b[0]+=a[0];
            for(j=1;j<n;j++)
                b[j]=a[j]+min(b[j],b[j-1]);
        }
        cout<<b[n-1]<<'\n';
    }
    return 0;
}

posted on 2019-10-21 13:03  我的昵称里必须得有mt  阅读(607)  评论(0编辑  收藏  举报

导航