codevs售货员的难题 —— 状态压缩动态规划[四星]
来源:互联网 发布:米表源码 编辑:程序博客网 时间:2024/04/26 12:28
题目链接:戳我~
题目描述 Description
某乡有n个村庄,有一个售货员,他要到各个村庄去售货,各村庄之间的路程s是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。
输入描述 Input Description
村庄数n和各村之间的路程(均是整数)
输出描述 Output Description
最短的路程
样例输入 Sample Input
3
0 2 1
1 0 2
2 1 0
样例输出 Sample Output
3
第一次打状压DP,以前只是听说不敢打…… 状压的思想核心还是比较易懂的
核心:
把状态压缩为一个二进制序列,用十进制保存,二进制中每一位都代表着不同的意义,比如说10,它的二进制是1010,可以理解为4号位和2号位的目标达成,1号和3号的目标没有达成。
压缩状态的目的是省空间,因为如果每一种状态开一个多维数组的话太占空间,并且转移也不好写,状压后转移写起来很方便,因为是二进制,主要通过位运算来实现它……
回到题目,看到n <= 15想到状压可以做,状压用在这里就是最外层从1for到2^n,这样就达到了枚举所有状态的目的,(具体实现详见代码),然后核心DP转移方程如下
dp[j][((1 << j-1) | i)] = min(dp[j][((1 << j-1) | i)],dp[k][i] + map[k][j]);
dp[i][j]表示的是从起点到i号点在j状态下的最短路径。
上面式子有一个条件,j没有走过而k走过(看不懂的话,下面有完整代码),那么上面式子的意思就是:从起点到j,状态从原来的i二进制第j-1项为0转移到为1时,取它本身和从k点状态i(即还没有走到j这个村子,因为此时i中对应的j的状态点为0),加上k到j的距离,这里要仔细想想。(位运算的优先级很低,(1 << j-1)优先算减法,然后再算<<,<<的意思是将原来的数字再二进制中左移多少位,1 << j-1位的含义是2^(j-1),2的j-1次方)。
最后时进行这一步:
for(int i = 2;i <= n;i ++){ ans = min(ans,dp[i][(1<<n)-1] + map[i][1]);}
这一步ans初值是INF,然后dp数组表示的是从起点到i点并且除了起点所有的村庄都走的最小值,然后再加上从i点到起点的距离,再所有情况中取最小值就是答案~
下面附上完整代码
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<deque>#include<algorithm>#include<cmath>using namespace std;const int size = 124500;int dp[23][size];int map[23][23];int main(){ int n; scanf("%d",&n); for(int i = 1;i <= n;i ++) for(int j = 1;j <= n;j ++) scanf("%d",&map[i][j]); memset(dp,63,sizeof(dp)); dp[1][1] = 0; for(int i = 0;i <= (1 << n);i ++) { for(int j = 1;j <= n;j ++) { if(((1 << j-1) & i) == 0) { for(int k = 1;k <= n;k ++) { if(((1 << k-1) & i)) { dp[j][((1 << j-1) | i)] = min(dp[j][((1 << j-1) | i)],dp[k][i] + map[k][j]); } } } } } int ans = 2147483640; for(int i = 2;i <= n;i ++) { ans = min(ans,dp[i][(1<<n)-1] + map[i][1]); } printf("%d",ans); return 0;}
- codevs售货员的难题 —— 状态压缩动态规划[四星]
- Luogu 1171 售货员的难题(状态压缩动态规划)
- codevs2596售货员难题——状态压缩dp
- CODEVS 2596 售货员的难题
- codevs 2596 售货员的难题
- 2596 售货员的难题[状态压缩&&优先队列]
- 状态压缩的动态规划
- 动态规划——Relocation 动态规划+状态压缩
- 模拟退火算法——解决售货员的难题
- 模拟退火算法——解决售货员的难题
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 动态规划!状态压缩
- 状态压缩动态规划
- 售货员的难题
- MongoDb 的 MMAPv1 和 WiredTiger 存储引擎空间对比(800万文档 )
- 软件工程之软件维护
- Understanding the differences between client/server and peer-to-peer networks
- QTP中的Action有什么作用?有几种?
- DataInputStream和DataOutputStream
- codevs售货员的难题 —— 状态压缩动态规划[四星]
- win7 下用vmware装mac虚拟机无法上网 —ios入门
- MFC框架程序剖析(1)
- 软工各阶段文档
- 八大排序算法小结
- NLP资源
- 第三方ProgressHUD进度条 技术分享
- hihoCoder1227 The Cats' Feeding Spots【暴力】
- 使用python统计出txt文档中含有某个单词的个数