程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> uva10285 - Longest Run on a Snowboard(記憶化搜索)

uva10285 - Longest Run on a Snowboard(記憶化搜索)

編輯:C++入門知識

uva10285 - Longest Run on a Snowboard(記憶化搜索)


題目:uva10285 - Longest Run on a Snowboard(記憶化搜索)


題目大意:給出N * N的矩陣,要求找到一條路徑,路徑上的值是遞減的,求這樣的路徑的最長長度。


解題思路:記憶話搜索。因為要求最長的路徑那麼就需要將所有的這樣的路徑找出,但是直接dfs會超時的。對於同一個位置,從這個點出發的最長路徑長度是固定的。所以在找的時候就要將這個位置的最長路徑算出來並且保存下來。一開始還擔心會走回頭路就是一直兜圈子。但是後面發現能往右走就不可能在從右邊的那個位置走回去,因為路徑上的值是要求遞減的。

dp【x】【y】代表從x,y這個位置開始能夠走的最長的路徑長度。


代碼:

#include 
#include 

const int N = 105;
const int M = 4;
const int dir[M][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};

int G[N][N];
int dp[N][N];
char name[N * 10];
int r, c;

int Max (const int a, const int b) { return a > b? a: b; }

int DP (int x, int y) {

	int& ans = dp[x][y];
	if (ans != -1)
		return ans;
	int newx, newy;
	for (int i = 0;  i < M; i++) {
		newx = x + dir[i][0];
		newy = y + dir[i][1];
		if (newx < 0 || newx >= r || newy < 0 || newy >= c)
			continue;
		if (G[x][y] > G[newx][newy])
			ans = Max (ans, DP (newx, newy) + 1);  //從這個位置開始四個方向的最長長度取最大值 
	}
	if (ans == -1)      //這個點走不出去
		ans = 1;
	return ans;	
}

int main () {
	
	int t;
	scanf ("%d", &t);
	while (t--) {

		scanf ("%s%d%d", name, &r, &c);
		for (int i = 0; i < r; i++)
			for (int j = 0; j < c; j++)
				scanf ("%d", &G[i][j]);
		
		memset (dp, -1, sizeof (dp));
		int ans = -1;
		for (int i = 0; i < r; i++) 從每個位置開始走都是有可能的取得最長路徑
			for (int j = 0; j < c; j++)
				ans = Max (ans, DP(i, j));
		printf ("%s: %d\n", name, ans);	
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved