Typesetting math: 100%

旅行商问题

91. 最短Hamilton路径

题意:旅行商问题,即从 1 走到 n 不重不漏,然后求最小距离。
题解:状态压缩dp,显然的是,要从某种状态到某种状态并且合法,然后取 min,然后全部遍历。所以设 dpi,j 的含义是,最后一个点是 i 点,然后走过了 j 这个 01 串的有 1 的点。然后要想的是顺序问题,那么我们必然是从上一个点推到 i 点,所以可以遍历所有点,然后得到 k 点,k 点一定是在这个 j 里面,然后那么 dpi,j=MINdpi,j,dpk,j(1>>i)
代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 21;
int dp[N][1 << N];
int w[N][N];
void solve() {
    int n;cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> w[i][j];
        }
    }
    memset(dp, 0x3f, sizeof dp);
    dp[0][1] = 0;
    for (int j = 0; j < 1 << n; j++) {
        for (int i = 0; i < n; i++) {
            if ((j >> i) & 1) {
                for (int k = 0; k < n; k++) {
                    if (((j - (1<<i)) >> k) & 1 ) {
                        dp[i][j] = min(dp[i][j], dp[k][j - (1 << i)] + w[k][i]);
                    }
                }
            }
        }
    }
    cout << dp[n - 1][(1 << n) - 1] << endl;
}
int main() {
    int t = 1;//cin >> t;
    while (t--) solve();
    return 0;
}

E - Traveling Salesman among Aerial Cities

题意:旅行商问题裸题,只不过多出来一项操作是不重不漏走完,并且还要回到原点,也没啥,如果理解了旅行商问题的 dp 方程代表含义,就很简单。
代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <cstring>
using namespace std;
typedef long long ll;

const ll N = 29;

struct node {
    ll x, y, z;
}a[22];
bool check(ll j, ll k, ll n) {
    for (ll i = 0; i < n; i++) {
        if (j >> i & 1) {
            for (ll ii = -1; ii <= 1; ii++) {
                ll d=  i + ii;
                d = max((ll)0, d);
                if ( k >> d  & 1 ) {
                    return 0;
                }
            }
        }
    }
    return 1;
}

ll w[N][N];
ll dp[N][1 << 18];
void solve() {
    ll n;cin >> n;
    for (ll i = 0; i < n; i++) cin >> a[i].x >> a[i].y >> a[i].z;
    for (ll i = 0; i < n; i++) {
        for (ll j = 0; j < n; j++) 
        {
            if (i == j)continue;
            w[i][j] = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y) + max((ll)0, a[j].z - a[i].z);
            w[j][i] = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y) + max((ll)0, a[i].z - a[j].z);
        }
    }
    memset(dp , 0x3f, sizeof dp);
    dp[0][1] = 0;
    for (ll j = 0; j < 1 << n; j++) {
        for (ll i = 0; i < n; i++) {
            for (ll k = 0; k < n; k++) {
                if ( (j - (1 << i) ) >> k & 1 && (j - (1 << i) )>=0) {
                    dp[i][j] = min(dp[i][j], dp[k][j - (1 << i)] + w[k][i]);
                }
            }
        }
    }
    ll ans = 0x7fffffff;
    for (ll i = 1; i < n; i++) ans = min(ans, dp[i][ (1 << n) - 1] + w[i][0]);//多出来了这个,就是知道了dp数组含义后,就很简单
    cout << ans << endl;
}
signed main() {
    ll t = 1;//cin >> t;
    while (t--) solve();
    return 0;
}
posted @   u_yan  阅读(221)  评论(0编辑  收藏  举报
编辑推荐:
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
阅读排行:
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库
点击右上角即可分享
微信分享提示