CodeForces 677D. Vanya and Treasure 枚举行列

 677D. Vanya and Treasure 

题意:

  给定一张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;
}
CF-677D
原文地址:https://www.cnblogs.com/ckxkexing/p/9513816.html