补题记录D. Explorer Space

D. Explorer Space

题意:有一个二维的网格图,每两个相邻的格子之间都有一条无向边,问对于每个点来说,走k步的最短路是多少。要求:从(i,j)开始就要从(i,j)结束
方法:DP
其实挺裸的一个dp,但是这里是有一个技巧的,等会说
状态表达:dp[i][j][k]表示走到(i,j),走了k步的最短路是多少。
状态转移:dp[i][j][k]=min(dp[i1][j][k1]+w1,dp[i][j1][k1]+w2,dp[i+1][j][k1]+w3,dp[i][j+1][k1]+w4)
但是注意题目要求,一定要从哪开始就从哪结束。
我们容易知道,当k是奇数的时候,一定不存在一条走回自己的路。
因为要过去又回来,所以过去回来的路径一定是重复的。所以我们只要求出走k2步的最短路,最后答案×2即可
我这个代码主要是建图比较麻烦了。好像有更方便的,我这个就是很普通的建图。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL,LL> PLL;
const int INF = 0x3f3f3f3f, N = 1e6 + 10;
inline int lc(int u) {return u << 1;}
inline int rc(int u) {return u << 1 | 1;}
inline int lowbit(int x) {return x & (-x);}
LL dp[600][600][30];
int g[600][600];
int h[N], nex[N], val[N], idx;
LL w[N];
inline void add(int a, int b, LL c) {
    val[idx] = b, w[idx] = c, nex[idx] = h[a], h[a] = idx ++ ;
}
inline void solve() {
    memset(h, -1, sizeof h);
    int n, m, kk; cin >> n >> m >> kk;
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) g[i][j] = (i - 1) * m + j;
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j < m; j ++ ) {
            LL x; cin >> x;
            int a = g[i][j], b = g[i][j + 1];
            add(a, b, x), add(b, a, x);
        }
    }
    for (int i = 1; i < n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            LL x; cin >> x;
            int a = g[i][j], b = g[i + 1][j];
            add(a, b, x), add(b, a, x);
        }
    }
    if (kk & 1) {
        for (int i = 1; i <= n; i ++ ) {
            for (int j = 1; j <= m; j ++ ) cout << -1 << ' ';
            cout << endl;
        }
        return ;
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            for (int k = 0; k <= kk; k ++ ) dp[i][j][k] = 1e9 + 7;
        }
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) dp[i][j][0] = 0;
    }
    kk /= 2;
    for (int k = 1; k <= kk; k ++ ) {
        for (int i = 1; i <= n; i ++ ) {
            for (int j = 1; j <= m; j ++ ) {
                int t = g[i][j];
                for (int p = h[t]; ~p; p = nex[p]) {
                    int now = val[p] - 1;
                    int x = now / m + 1, y = now % m + 1;
                    dp[i][j][k] = min(dp[i][j][k], dp[x][y][k - 1] + w[p]);
                }
            }
        }
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) cout << 2ll * dp[i][j][kk] << ' ';
        cout << endl;
    }
}
int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
//    int t; cin >> t;
//    while (t -- )
    solve();
    return 0;
}
posted @   Time_Limit_Exceeded  阅读(138)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示