[CODEVS2800]送外卖(状压dp)
2016-04-24 20:31
246 查看
题目描述
传送门题解
预处理两两之间的最短路dis状态:f[i][j]表示最后到达了j,之前经过的点状态为i的最短路。
转移:f[i|(1<<(k-1))][k]=min(f[i|(1<<(k-1))][k],f[i][j]+dis[j][k]);其中i表示之前的状态,j表示之前经过的点,k表示将要到达的点。
初始化:f[1][1]=0,其余为正无穷
目标:f[(1<<n)-1][i]+dis[i][1](因为最后要回到1点)
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N=17; const int INF=2e9; int n,tot,ans=INF; int dis ,f[1<<N] ; inline void floyed(){ for (int k=1;k<=n;++k) for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) if (i!=j&&j!=k) if (dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j]; } int main(){ scanf("%d",&n);++n; for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) scanf("%d",&dis[i][j]); floyed(); memset(f,0x7f,sizeof(f)); f[1][1]=0; tot=(1<<n)-1; for (int i=1;i<=tot;++i) for (int j=1;j<=n;++j) if ((1<<(j-1))&i) for (int k=1;k<=n;++k) f[i|(1<<(k-1))][k]=min(f[i|(1<<(k-1))][k],f[i][j]+dis[j][k]); for (int i=1;i<=n;++i) ans=min(ans,f[tot][i]+dis[i][1]); printf("%d\n",ans); }
总结
注意dp的目标。注意循环的顺序。
相关文章推荐
- javascript字母大小写转换的4个函数详解
- Flink中task之间的数据交换机制
- HDU 4183 网络流
- Java 占位符
- Genymotion 启动报错
- 第一冲刺阶段工作总结04
- 团队冲刺07
- linux环境下MySQL的日志监控
- 错误:the public type XXX must be defined in its own file.
- C++学习(二)——指针与动态内存分配
- 152. Maximum Product Subarray
- Servlet课程0424(三) 通过继承HttpServlet来开发Servlet
- 说一下linux中shell的后台进程与前台进程
- 二叉树的镜像
- Jquery基本知识
- 二维数组,矩形数组 集合
- poj3414 Pots BFS
- HDU5671Matrix(矩阵行列交换)
- 20145208 《Java程序设计》第8周学习总结
- 20144303 《Java程序设计》第八周学习总结