题意:
给定一张n*m的图,图上每个点标有1~p的值,你初始在(1,1)点,你必须按照V:1,2,3...p的顺序走图上的点,问你如何走时间最少。
思路:
我一开始想的思路感觉很巧妙,但是TLE了。就是把不同值的点放在不同的vector中,然后类似dp的从2更新最小距离到p。因为我这是暴力枚举点的,复杂度不对。后来发现这个思路还需要优化一下,就是把同一行的点放在一起,for一遍这一行属于V的点,就可以更新本行的信息了,再向下把列中属于v+1的更新了。复杂度就降到了O(n^3);
%和学习的是这份代码:huhuhu
#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cmath> #include <queue> #include <list> #include <map> #include <set> using namespace std; ///#pragma GCC optimize(3) ///#pragma comment(linker, "/STACK:102400000,102400000") //c++ #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << " "; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; typedef pair<ll ,ll > pll; typedef pair<int ,int > pii; typedef pair<int,pii> p3; ///priority_queue<int> q;//这是一个大根堆q ///priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second ///#define endl ' ' #define OKC ios::sync_with_stdio(false);cin.tie(0) #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行 #define REP(i , j , k) for(int i = j ; i < k ; ++i) ///priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFFLL; //2147483647 const ll nmos = 0x80000000LL; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3fLL; //18 const int mod = 1e9+7; const double PI=acos(-1.0); // #define _DEBUG; //*// #ifdef _DEBUG freopen("input", "r", stdin); // freopen("output.txt", "w", stdout); #endif /*-----------------------showtime----------------------*/ const int maxn = 400; int dp[maxn][maxn], mp[maxn][maxn]; vector<pii>v[maxn*maxn]; vector<int>col[maxn]; bool vis[maxn]; int main(){ int n,m,tp; scanf("%d%d%d", &n, &m, &tp); for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ int op; scanf("%d", &op); mp[i][j] = op; if(op==1)dp[i][j] = i+j-2; else dp[i][j] = inf; v[op].pb(pii(i,j)); } } for(int i=1; i<tp; i++){ for(int j=1; j<= max(n,m); j++){ col[j].clear(); vis[j] = false; } for(pii p : v[i+1]){ col[p.se].pb(p.fi); } for(pii p: v[i]){ vis[p.fi] = true; } for(int j=1; j<=n; j++) if(vis[j]){ int best = inf; for(int k = 1; k<=m; k++){ best++; if(mp[j][k] == i) best = min(best, dp[j][k]); for(int y : col[k]){ dp[y][k] = min(dp[y][k], best + abs(y-j)); } } best = inf; for(int k = m; k>=1; k--){ best++; if(mp[j][k] == i) best = min(best, dp[j][k]); for(int y : col[k]){ dp[y][k] = min(dp[y][k], best + abs(y-j)); } } } } for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(mp[i][j]==tp){ printf("%d ", dp[i][j]); } } } return 0; }