日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

[UVA10285],最长滑雪路径(dp)

發布時間:2023/12/13 综合教程 25 生活家
生活随笔 收集整理的這篇文章主要介紹了 [UVA10285],最长滑雪路径(dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Description

原題鏈接

和poj1088同樣的題目

【題目描述】

benben喜歡滑雪。(以下簡敘)在一個(R*C(R,Cleq100))的整數矩陣上找一條高度嚴格遞減的最長路。起點任意,但每次只能沿著上下左右4個方向之一走一格,并且不能走出矩陣外。如圖所示,最長路是按照高度25,24,23,...,2,1 這樣走,長度為25。矩陣中的數均為0~100.

【輸入格式】

有多組數據。

第一行為一個整數N,表示數據組數。 對于每組數據,第一行包括一個字符串和兩個整數R,C,為此滑雪者的姓名和矩陣的長寬。

【輸出格式】

對于每組數據,輸出一行,格式為: name: answer

name為當前數據的滑雪者姓名,answer為你的答案。

【輸入輸出樣例】

輸入:

2
Feldberg 10 5
56 14 51 58 88
26 94 24 39 41
24 16 8 51 51
76 72 77 43 10
38 50 59 84 81
5 23 37 71 77
96 10 93 53 82
94 15 96 69 9
74 0 62 38 96
37 54 55 82 38
Spiral 5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

輸出:

Feldberg: 7
Spiral: 25

二、Soulution

這是一道動態規劃的題目,(dp[i][j])表示到達((i,j))點的時候最長路的值,初始化都為1

首先按照整數矩陣的值的大小對每個點從大到小排序,然后更新每個點的(dp[][])值,也就是狀態轉移;

當((i,j))點的整數值小于周圍的點并且,(dp[i][j])小于周圍某個點的(dp+1)的時候,表示周圍的某個點可以下滑到((i,j)),那么更新(dp[i][j])為周圍那個點的(dp+1)。

這里為什么要先從大到小排序呢?可以將整個整數矩陣理解成一座座山相連,局部最大的值就是一個山的山峰。我們想得到其中一個山的高度(由該山峰出發的最大下滑距離),由于一開始dp值都是1,必須先得到較高的點的dp值,才能根據它更新較低點的dp值。

《算法基礎與在線實踐》書上動態規劃這一節有講這個poj1088的題目,遞推也有兩種思路。

一種是“人人為我”,就是由上下左右的點更新當前的點的dp值(也就是我下面代碼采用的)

另一種就是“我為人人”,就是由當前的點,更新上下左右的點的dp值

當然兩者更新的時候都要先判度四周的點是否符合條件:一是沒有越界;二是要從高的點滑向低的點;

#include<iostream>
#include<string> 
#include<vector>
#include<algorithm>
using namespace std;
struct Node{
	int value;
	int i;
	int j;
};

bool cmp(const Node a, const Node b) //結構體的比較函數 
{
	return a.value > b.value; 
}
int main()
{
	int t;
	cin >> t;
	string name;
	int row, col;
	while(t--) {
		cin >> name >> row >> col;
		
		vector<vector<int>> map(row, vector<int>(col, 0));
		vector<vector<int>> dp(row, vector<int>(col, 1));  // dp[i][j]表示到(i,j)點的時候最大的下滑距離 
														   // 初始都是1?。。?
		struct Node nodes[row*col];
		
		int k = 0;
		for(int i = 0; i < row; ++i) {
			for(int j = 0; j < col; ++j) {
				cin >> map[i][j];
			
				nodes[k].i = i;
				nodes[k].j = j;
				nodes[k].value = map[i][j];
				k++;
			}
		}
	    
	    sort(nodes, nodes + row*col, cmp);  // 按照value從大到小排序 
	    
	    dp[nodes[0].i][nodes[0].j] = 1;
	    int ans = 0;
	    for(int i = 1; i < row*col; ++i) {
	    	
	    	int x = nodes[i].i;
	    	int y = nodes[i].j;
	    	int value = nodes[i].value;
	    	
			// 由上、下、左、右的點更新該點的值 
			if (y-1 >= 0 && value < map[x][y-1]) {
				dp[x][y] = max(dp[x][y], dp[x][y-1] + 1);	
			}
			if (y+1 < col && value < map[x][y+1]) {
				dp[x][y] = max(dp[x][y], dp[x][y+1] + 1);	
			}
	    	if (x-1 >= 0 && value < map[x-1][y]) {
	    		dp[x][y] = max(dp[x][y], dp[x-1][y] + 1);
			}
			if (x+1 < row && value < map[x+1][y]) {
				dp[x][y] = max(dp[x][y], dp[x+1][y] + 1);	
			}		

			ans = max(ans, dp[x][y]);

		}
		
		cout << name << ":" << " " << ans << endl;
	}
	
	return 0;
	
 } 

總結

以上是生活随笔為你收集整理的[UVA10285],最长滑雪路径(dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。