2020牛客寒假算法基础集训营3——J.牛牛的宝可梦Go【最短路 DP(01背包) 复杂度优化】(附优化分析)
題目傳送門
題目描述
牛牛所在的W市是一個不太大的城市,城市有n個路口以及m條公路,這些雙向連通的公路長度均為1,保證你可以從一個城市直接或者間接移動到所有的城市。牛牛在玩寶可夢Go,眾所周知呢,這個游戲需要到城市的各個地方去抓寶可夢,假設(shè)現(xiàn)在牛牛知道了接下來將會刷出k只寶可夢,他還知道每只寶可夢的刷新時刻、地點以及該寶可夢的戰(zhàn)斗力,如果在寶可夢刷新時,牛牛恰好在那個路口,他就一定能夠抓住那只寶可夢。
由于游戲公司不想讓有選擇恐懼癥的玩家為難,所以他們設(shè)計不存在任何一個時刻同時刷出兩只及以上的寶可夢。
假設(shè)不存在任何一個時刻會同時刷出兩只寶可夢,牛牛一開始在城市的1號路口,最開始的時刻為0時刻,牛牛可以在每個時刻之前移動到相鄰他所在位置的路口,當然他也可以保持原地不動,他現(xiàn)在想知道他能夠捕獲的寶可夢戰(zhàn)斗力之和最大為多少?
輸入描述:
第一行輸入兩個正整數(shù) n , m , ( 1 ≤ n ≤ 200 , 0 ≤ m ≤ 10000 ) n,m,(1 \leq n \leq 200,0 \leq m \leq 10000) n,m,(1≤n≤200,0≤m≤10000)表示城市的路口數(shù)目以及公路數(shù)目。
接下來m行每行兩個正整數(shù) u , v ( 1 ≤ u , v ≤ n ) u,v(1 \leq u,v \leq n) u,v(1≤u,v≤n)表示一條長度為1鏈接兩個路的公路。
接下來一行輸入一個正整數(shù) k ( 1 ≤ k ≤ 1 0 5 ) k(1 \leq k \leq 10^5) k(1≤k≤105)表示寶可夢的數(shù)目。
接下來輸入k行,每行三個正整數(shù) t i , p i , v a l i ( 1 ≤ p i ≤ n , 1 ≤ t i , v a l i ≤ 1 0 9 ) t_i,p_i,val_i(1 \leq p_i \leq n,1 \leq t_i,val_i \leq 10^9) ti?,pi?,vali?(1≤pi?≤n,1≤ti?,vali?≤109),分別表示寶可夢刷新的時間、地點、以及戰(zhàn)斗力,輸入數(shù)據(jù)保證不會出現(xiàn)在同一時刻刷出多只寶可夢。
輸出描述:
輸出一個整數(shù)表示牛牛能捉到的寶可夢戰(zhàn)斗力之和最大是多少。
輸入
3 2
1 2
2 3
3
1 1 5
2 3 10
3 2 1
1 0
3
1 1 100
100 1 10000
10000 1 1
3 2
1 2
2 3
1
1 3 1000000000
3 2
1 2
2 3
1
1 2 1000000000
輸出
11
10101
0
1000000000
備注:
輸入數(shù)據(jù)保證不會出現(xiàn)在同一時刻刷出多只寶可夢。
題解
- 既然要在不同的城市移動,想要盡可能捕獲多的寶可夢,那么就需要走最短路: F l o y d Floyd Floyd
- 接下來我們需要捕捉寶可夢,很顯然需要按照時間升序?qū)毧蓧襞判?/strong>
- 定義 d p [ i ] : 最 后 捕 獲 的 寶 可 夢 為 i 的 最 大 價 值 dp[i]:最后捕獲的寶可夢為i的最大價值 dp[i]:最后捕獲的寶可夢為i的最大價值
- 然后我們考慮狀態(tài)轉(zhuǎn)移,可以發(fā)現(xiàn),對于 當 前 寶 可 夢 所 在 點 p o s i 當前寶可夢所在點pos_i 當前寶可夢所在點posi?, 前 一 寶 可 夢 所 在 點 p o s j 前一寶可夢所在點pos_j 前一寶可夢所在點posj?,如果 兩 只 寶 可 夢 刷 新 時 間 < = d i s [ p o s i ] [ p o s j ] 兩只寶可夢刷新時間 <= dis[pos_i][pos_j] 兩只寶可夢刷新時間<=dis[posi?][posj?],那么說明可以從 d p [ j ] dp[j] dp[j] 轉(zhuǎn)移到 d p [ i ] dp[i] dp[i] ,即可以更新 d p [ i ] = d p [ j ] + v a l i dp[i]=dp[j]+val_i dp[i]=dp[j]+vali?
- 注意題目并不保證圖聯(lián)通,所以初始化地圖 d i s = i n f dis=inf dis=inf
- 目前來看已經(jīng)可以解決問題了,但是發(fā)現(xiàn)寶可夢數(shù)量 k < = 1 e 5 k<=1e5 k<=1e5,而 01背包dp過程復(fù)雜度 k 2 k^2 k2,時間復(fù)雜度肯定是不允許的。
- 我們發(fā)現(xiàn),地圖點數(shù) n < = 200 n<=200 n<=200,因此任意兩點最短路最多是199(為了好看當作200即可)。
考慮上圖情況,如果 j → i j \rightarrow i j→i時間超過了200,說明我們在這段時間內(nèi),可以去到任意位置去找其他寶可夢,可以不從 j j j 直接到 i i i,那么我們知道01背包內(nèi)層循環(huán)順序是逆序的,也就是說,當我們判斷 j → i j \rightarrow i j→i 的時候,我們已經(jīng)經(jīng)過了 k k k 點,也就是說,我們已經(jīng)得到了 j → k → i j \rightarrow k \rightarrow i j→k→i 的最優(yōu)解,所以并不需要再次重復(fù)計算 j → i j \rightarrow i j→i。 - 但是我們可以直接讓 Δ t > = 200 \Delta t>=200 Δt>=200 的直接跳過么,很顯然不可以,因為如果 j → i > = 200 j \rightarrow i >=200 j→i>=200,但是實際上 j → i j \rightarrow i j→i 的價值更優(yōu)于 j → k → i j \rightarrow k \rightarrow i j→k→i;或者沒有 k k k 供我們轉(zhuǎn)移,那么我們就不可以直接跳過 j j j。
- 但其實分析到這里的話,隨便怎么圍繞常熟優(yōu)化一下都是可以 A c c e p t Accept Accept 的,我采用的是每次找最靠近的 200 200 200 個寶可夢,這樣復(fù)雜度就是 O ( 200 k ) O(200k) O(200k) 了。
AC-Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int maxn = 2e5 + 7;int dis[201][201];void floyd(int n) {for (int k = 1; k <= n; ++k)for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); }struct Node {int pos, t, val;Node() {}Node(int pos, int t, int val) :pos(pos), t(t), val(val) {} }node[maxn];ll dp[maxn];int main() {int n, m; while (cin >> n >> m) {for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)dis[i][j] = i == j ? 0 : 0x3f3f3f3f;for (int i = 0; i < m; ++i) {int u, v; cin >> u >> v;dis[u][v] = dis[v][u] = 1;}floyd(n);int k; cin >> k;for (int i = 1; i <= k; ++i) {cin >> node[i].t >> node[i].pos >> node[i].val;dp[i] = -1e18;}sort(node + 1, node + 1 + k, [](Node a, Node b) {return a.t < b.t; });node[0].pos = 1, node[0].t = 0; // 初始化牛牛位置dp[0] = 0;ll ans = 0;for (int i = 1; i <= k; ++i) {for (int j = i - 1; j >= 0; --j) {if (i - j >= 200) break; // 常數(shù)優(yōu)化if (dis[node[i].pos][node[j].pos] <= node[i].t - node[j].t)dp[i] = max(dp[i], dp[j] + node[i].val);}ans = max(ans, dp[i]);}cout << ans << endl;}return 0; }總結(jié)
以上是生活随笔為你收集整理的2020牛客寒假算法基础集训营3——J.牛牛的宝可梦Go【最短路 DP(01背包) 复杂度优化】(附优化分析)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux的vps主机安装图形界面并远程
- 下一篇: 2021-2025年中国卡波芬金行业市场