[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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Javascript系列——对象元素的数
- 下一篇: m,mm,mmm的用法