1. 程式人生 > >動態規劃練習題(1)最小通行費

動態規劃練習題(1)最小通行費

【題目描述】

一個商人穿過一個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,所以只能向下或者向右走,想到這步就很好辦了。狀態轉移方程也很好推的……注意邊界(i==1和j==1時)的狀態只能由一個方向推出

#include <iostream>
#include <cstdio>
using namespace std;
int n,f[1000][1000];
int main()
{
	cin>>n;
	for(int i=1;i<=n;++i)
	for(int j=1;j<=n;++j)
	cin>>f[i][j];
	for(int i=1;i<=n;++i)
	for(int j=1;j<=n;++j){
		if(i==1 and j==1) continue;
		if(i==1){
			f[i][j]+=f[i][j-1];
		}
		else if(j==1) f[i][j]+=f[i-1][j];
		else f[i][j]+=min(f[i-1][j],f[i][j-1]);
	} 
	cout<<f[n][n]<<endl;
	return 0;
}