AcWing 731. 毕业旅行问题(每日一题)

2024-04-05 01:20

本文主要是介绍AcWing 731. 毕业旅行问题(每日一题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题链接:731. 毕业旅行问题 - AcWing题库

此题难度较大,是2019年字节跳动校招题,里面涉及位运算与状态压缩DP,不会的可以去学习,此题根据个人量力而行。

建议看一下y总的讲解:AcWing 731. 毕业旅行问题(每日一题)_哔哩哔哩_bilibili

目录

题目:

解题思路:

代码实现:

写在最后:


题目:

小明目前在做一份毕业旅行的规划。

打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次。

由于经费有限,小明希望能够通过合理的路线安排尽可能的省些路上的花销。

给定一组城市和每对城市之间的火车票的价钱,找到每个城市只访问一次并返回起点的最小车费花销。

注意北京为 1 号城市

输入格式

第一行包含一个正整数 n,表示城市个数。

接下来输入一个 n 行 n列的矩阵,表示城市间的车票价钱。

输出格式

输出一个整数,表示最小车费花销。

数据范围

1<n≤20,包括北京
车票价格均不超过 1000 元。

输入样例:

4
0 2 6 5
2 0 4 4
6 4 0 2
5 4 2 0

输出样例:

13

说明

共 4 个城市,城市 1 和城市 1 的车费为 0,城市 1 和城市 2 之间的车费为 2,城市 1 和城市 3 之间的车费为 6,城市 1 和城市 4 之间的车费为 5,以此类推。

假设任意两个城市之间均有单程票可买,且价格均在 1000 元以内,无需考虑极端情况。


解题思路:

此题主要用了状态压缩DP,它的f[i,j]设置的很巧妙,把i化成二进制,比如有五个城市,初始为00001,最后一位为北京当前就在北京。下一个比如武汉花费小(武汉第三个城市)那就是二进制为00101,又到达上海(第五个城市)那就是10101……当达到目标状态二进制为11111,把所有城市都标记一遍,那么此次完成了此次旅行,还一个问题那就是我还要回北京啊,既然要回北京那就要找最后一个到达的城市,从最后到达的城市坐高铁直接回北京,那么我们最后还要枚举一遍最后到达的城市,在所有城市里面加上回北京的费用,取一个最小值即是答案。

一些细节问题以及一些位运算等问题以图片手写解答一下:


代码实现:

#include<iostream>
#include<cstring>
using namespace std;
const int N=20,M=1<<N,inf=0x3f3f3f;
int n;
int w[N][N],f[M][N];//w[i][j]表示花费数组
//f[i][j]表示i为二进制标记数组,j表示到达j个城市的最小花费
int main(){cin>>n;for(int i=0;i<n;i++){for(int j=0;j<n;j++){cin>>w[i][j];}}memset(f,inf,sizeof(f));//初始无穷大f[1][0]=0;//2^0=1第一个北京地点被标记为1for(int i=1;i<1<<n;i+=2){//1~2^n都遍历一遍//i+2是把第一个北京也给同时被标记,加一二进制逢二进一,会变成10,北京又被置成0没有被标记,所以加2还是1for(int j=0;j<n;j++){//j遍历到达第j个城市if(i>>j&1){//此时处于j城市,看看是否i中包含j(被标记),i的二进制表示第j位是否为1for(int k=0;k<n;k++){//k表示中转城市到达j城市if(i-(1<<j)>>k&1){//判断第i个状态除去第j个城市是否包含第k个城市f[i][j]=min(f[i][j],f[i-(1<<j)][k]+w[k][j]);}}}}}int res=inf;for(int i=1;i<n;i++){//枚举最后一个到达的城市res=min(res,f[(1<<n)-1][i]+w[i][0]);//为了二进制方便下标从0开始}cout<<res<<endl;return 0;
}

写在最后:

此题对于博主这样的cj来说比较难了,都是按照博主自己的理解去写的,会有一些不是很准确的地方,学了很长时间,似懂非懂的感觉,大佬勿喷。主要还是状态的定义利用二进制去标记那个地方第一次见,感觉很巧妙,再就是写代码中不经常使用位运算对于y总的代码看起来也比较困难,还有很多地方需要好好学习一次,感觉跟着y总的每日一题学到了不少东西,以后还需继续加油,文章若有错误的地方请各位大佬指出,一起学习进步。

PS:第一张图片来组y总讲解  作者:yxc

这篇关于AcWing 731. 毕业旅行问题(每日一题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877313

相关文章

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo