第九章 動態規劃-1287:最低通行費

1287:最低通行費

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2843 通過數: 2095
【題目描述】
一個商人穿過一個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。


思路:由題意可得:第一行所有點只能一直右走,所以f[i][j] = a[i][j] + f[i][j-1], 同理第一列的點也只能一直向下走,f[i][j] = a[i][j] + f[i-1][j] 。
預處理完後,餘下所有點到達該點的最小費用都等於min(到右邊的點的最小費用, 到下面的點的最小費用)+該點的費用。
狀態轉移方程:f[i][j] = min(f[i-1][j], f[i][j-1]) + a[i][j]
在這裏插入圖片描述

#include <iostream>
#include <cstdio>
#define N 101
using namespace std;
int f[N][N], a[N][N], n;
int ans;

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) 
        for(int j = 1; j <= n; j++) {
            scanf("%d", &a[i][j]);
            if(i == 1) f[i][j] = a[i][j] + f[i][j-1];//第一行前後2個數相加 
            if(j == 1) f[i][j] = a[i][j] + f[i-1][j];//第一列上下2個數相加
        }
    for(int i = 2; i <= n; i++)//第二行開始右走或下走 選取路費疊加 
        for(int j = 2; j <= n; j++) f[i][j] = min(f[i-1][j], f[i][j-1]) + a[i][j];
    printf("%d\n", f[n][n]);//輸出到終點的小費用值 
    return 0;
   } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章