AtCoder題解 —— AtCoder Beginner Contest 188 —— E - Peddler —— 動態規劃
技術標籤:OJ題解# AtCoder題解AtCoder題解ABC188E題Peddler動態規劃
題目相關
題目連結
AtCoder Beginner Contest 188 E 題,https://atcoder.jp/contests/abc188/tasks/abc188_e。
Problem Statement
In Takahashi Kingdom, there are
N
N
N towns, called Town
1
1
1 through Town
N
N
N.
There are also
M
M
M roads in the kingdom, called Road
1
1
Gold is actively traded in this kingdom. At Town
i
i
i, you can buy or sell
1
1
1 kilogram of gold for
A
i
A_i
Takahashi, a traveling salesman, plans to buy
1
1
1 kilogram of gold at some town, traverse one or more roads, and sell
1
1
1 kilogram of gold at another town.
Find the maximum possible profit (that is, the selling price minus the buying price) in this plan.
Input
Input is given from Standard Input in the following format:
N M
A1 A2 ... AN
X1 Y1
X2 Y2
.
.
.
XM YM
Output
Print the answer.
Sample 1
Sample Input 1
4 3
2 3 1 5
2 4
1 2
1 3
Sample Output 1
3
Explaination
We can achieve the profit of
3
3
3 yen, as follows:
At Town
1
1
1, buy one kilogram of gold for
2
2
2 yen.
Traverse Road
2
2
2 to get to Town
2
2
2.
Traverse Road
1
1
1 to get to Town
4
4
4.
At Town
4
4
4, sell one kilogram of gold for
5
5
5 yen.
Sample 2
Sample Input 2
5 5
13 8 3 15 18
2 4
1 2
4 5
2 3
1 3
Sample Output 2
10
Explaination
We can achieve the profit of
10
10
10 yen, as follows:
At Town
2
2
2, buy one kilogram of gold for
8
8
8 yen.
Traverse Road
1
1
1 to get to Town
4
4
4.
Traverse Road
3
3
3 to get to Town
5
5
5.
At Town
5
5
5, sell one kilogram of gold for
18
18
18 yen.
Sample 3
Sample Input 3
3 1
1 100 1
2 3
Sample Output 3
-99
Explaination
Note that we cannot sell gold at the town where we bought the gold, which means the answer may be negative.
Constraints
- 2 ≤ N ≤ 2 × 1 0 5 2≤N≤2×10^5 2≤N≤2×105
- 1 ≤ M ≤ 2 × 1 0 5 1≤M≤2×10^5 1≤M≤2×105
- 1 ≤ A i ≤ 1 0 9 1≤A_i≤10^9 1≤Ai≤109
- 1 ≤ X i < Y i ≤ N 1≤Xi<Yi≤N 1≤Xi<Yi≤N
- ( X i , Y i ) ≠ ( X j , Y j ) ( i ≠ j ) (Xi,Yi)≠(Xj,Yj)(i≠j) (Xi,Yi)=(Xj,Yj)(i=j)
- All values in input are integers.
題解報告
題目翻譯
在高橋的王國,有
N
N
N 個城鎮,編號從
1
1
1 到
N
N
N。
在王國裡有
M
M
M 條道路,稱為道路
1
1
1 到道路
M
M
M。穿過第
i
i
i 條道路,可以從城鎮
X
i
X_i
Xi 到城鎮
Y
i
Y_i
Yi,但是這第
i
i
i 條道路,不會從城鎮
Y
i
Y_i
Yi 到
X
i
X_i
Xi。
在王國裡,黃金交易非常活躍。在城鎮
i
i
i,你可以使用
A
i
A_i
Ai 日圓購買
1
1
1 公斤黃金。
高橋,一個旅行商,計劃在某個城鎮買
1
1
1 公斤黃金,通過一條或者多條道路,在其他城鎮賣出這些黃金。
請找出最大的收益。
題目分析
根據題目的描述,找出最大值,基本上就是一個動態規劃題目。雖然本題看起來像是資料結構圖論方面的內容,DAG 問題。
由於本題有一個限制,也就是
1
≤
X
i
<
Y
i
≤
N
1≤Xi<Yi≤N
1≤Xi<Yi≤N,我們可以從
N
N
N 到
1
1
1 進行動態規劃。
假設
D
P
[
i
]
DP[i]
DP[i] 為第
i
i
i 個城鎮可以到達的所有城鎮中黃金價格最高,不包括第
i
i
i 個城鎮。ans 為 dp[i]-a[i] 的最大值。
樣例 1 資料分析
根據樣例資料,我們可以繪製出如下的圖。
上圖中,黑色表示城鎮編號,綠色表示道路,紅色表示這個城鎮黃金價格。這樣我們將有以下兩個資料結構,第一個為黃金價格表
a
a
a。
a[i] | 數值 |
---|---|
1 | 2 |
2 | 3 |
3 | 1 |
4 | 5 |
一個是連線矩陣 a d j adj adj。
adj[i] | 值 |
---|---|
1 | 2 |
3 | |
2 | 4 |
對應的 D P DP DP 陣列初始化值都是 -1e9。這樣我們從 N N N 到 1 1 1 ,尋找第 i i i 個城鎮相鄰的城鎮最高黃金價格。如果第 i i i 個城鎮沒有相連的城鎮,就吧 D P DP DP 陣列對應值寫為 a [ i ] a[i] a[i]。
第 4 4 4 個城鎮
由於沒有相連的城鎮,DP[4]=a[4]。這樣 D P DP DP 陣列的值變為
DP[i] | 數值 | ans |
---|---|---|
1 | -1e9 | -1e9 |
2 | -1e9 | – |
3 | -1e9 | – |
4 | 5 | – |
第 3 3 3 個城鎮
由於沒有相連的城鎮,DP[3]=a[3]。這樣 D P DP DP 陣列的值變為
DP[i] | 數值 | ans |
---|---|---|
1 | -1e9 | -1e9 |
2 | -1e9 | |
3 | 1 | |
4 | 5 |
第 2 2 2 個城鎮
該城鎮可以到城鎮 4 4 4,因此,我們取 DP[2] 和 DP[5] 的最大值,也就是 DP[5],即 DP[2]=5。ans 的值也發生改變,變為 max(ans, DP[2]-a[2]),也就是在 2 2 2 城鎮買, 5 5 5 城鎮賣的差價,也就是 5 − 3 = 2 5-3=2 5−3=2。
DP[i] | 數值 | ans |
---|---|---|
1 | -1e9 | 2 |
2 | 5 | |
3 | 1 | |
4 | 5 |
第 1 1 1 個城鎮
該城鎮可以到城鎮 2 2 2 和 3 3 3。我們先到城鎮 2 2 2,這樣 D P [ 1 ] = m a x ( D P [ 1 ] , D P [ 2 ] ) = 5 DP[1]=max(DP[1], DP[2])=5 DP[1]=max(DP[1],DP[2])=5。再到城鎮 3 3 3,這樣 D P [ 1 ] = m a x ( D P [ 1 ] , D P [ 3 ] ) = 5 DP[1]=max(DP[1], DP[3])=5 DP[1]=max(DP[1],DP[3])=5。這樣遍歷完連線表,表示從 1 1 1 連線的城鎮最高黃金價格為 5 5 5。因此,我們從 1 1 1 城鎮購買黃金,到其他城鎮賣出,可以獲得的價差為 5 − 2 = 3 5-2=3 5−2=3,跟新 ans 的資料。
DP[i] | 數值 | ans |
---|---|---|
1 | 5 | 3 |
2 | 5 | |
3 | 1 | |
4 | 5 |
資料範圍估計
從上面分析中,我們只有減法,而且 A i A_i Ai 的最大資料為 1 0 9 10^9 109,因此 int 可以。
AC 程式碼
//https://atcoder.jp/contests/abc188/tasks/abc188_e
//E - Peddler Editorial
#include <bits/stdc++.h>
using namespace std;
//如果提交到OJ,不要定義 __LOCAL
//#define __LOCAL
typedef long long ll;
int main() {
#ifndef __LOCAL
//這部分程式碼需要提交到OJ,本地除錯不使用
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#endif
ll n, m;
cin>>n>>m;
vector<int> a(n+1);
for (int i=1; i<=n; i++) {
cin>>a[i];
}
//連線表
vector<vector<int>> adj(n+1);
for (int i=1; i<=m; i++) {
int u,v;
cin>>u>>v;
//建立連線表
adj[u].emplace_back(v);
}
vector<int> dp(n+1, -1e9);//最高價格
int ans=-1e9;
for (int i=n; i>=1; i--) {
//在 adj[i] 中遍歷找出黃金最高價
for (int j=0; j<adj[i].size(); j++){
dp[i] = max(dp[i], dp[adj[i][j]]);
}
ans = max(ans, dp[i]-a[i]);
dp[i] = max(dp[i], a[i]);//更新價格
}
cout<<ans<<"\n";
#ifdef __LOCAL
//這部分程式碼不需要提交到OJ,本地除錯使用
system("pause");
#endif
return 0;
}
時間複雜度
O ( N + M ) O(N+M) O(N+M)。
空間複雜度
O ( N ) O(N) O(N)。