VIJOS1456最小总代价
2015-12-20 20:20
246 查看
题目大意
给定一个含有n个点完全连通图,每条边权值<=10000,求经过所有点各一次的路径的各边权值之和的最小值n<=16
分析
经典的状态压缩dp问题f[i][j]=x表示经过点的集合为i,最后一个经过的点为j时,当前最小总代价为x
(集合状态可以用二进制表示)
f[{j}][j]=0
f[i][j]=min{f[i-{j}][k]+a[k][j]}(i包含j和k,k!=j)
时间复杂度O(n*n*2^n)
有2种实现方法,一种是记忆化搜索,另一种是递推。
我的递推写丑了,跑的好慢。
代码
[code]#include<cstdio> const int oo=0x3fffffff; int n,a[50][50],f[70000][20],t; int main(){ scanf("%d",&n); for (int i=0;i<n;i++) for (int j=0;j<n;j++) scanf("%d",&a[i][j]); t=(1<<n)-1;//不能写成1<<n-1 for (int i=0;i<=t;i++) for (int j=0;j<n;j++) f[i][j]=oo; for (int i=0;i<n;i++) f[1<<i][i]=0; int te; for (int i=1;i<=t;i++){ for (int j=0;j<n;j++) if (i&&(1<<j)) for (int k=0;k<n;k++) if ((i&&(1<<k))&&(j!=k)){ te=f[i^(1<<j)][k]+a[k][j];//用没经过j,最后到达点k的状态更新 if (te<f[i][j]) f[i][j]=te; } } te=oo; for (int i=0;i<n;i++) if (f[t][i]<te) te=f[t][i]; printf("%d\n",te); return 0; }
相关文章推荐
- POJ 1001 解题报告
- LDR ADR
- 苹果的开发者账号
- html5声频audio和视频video
- 【mysql】高可用集群之MMM
- linux-->cat命令详解
- 20135213 20135231 信息安全系统设计基础课程第五次实验报告
- 《挑战程序设计竞赛》2.5 最小生成树 POJ3723 3169 1258 2377 2395 AOJ2224(1)
- Android中折线图实现方法(各类图表实现)
- Android QQ,WeChat,Weibo三方登陆
- 解决ViewPager 放在ListView 头位置事件冲突
- Appium__客户端签到
- 期末总结
- android 展示单选列表对话框 builder.setSingleChoiceItems
- Linux常见服务(守护进程)
- Openrisc的or1200
- 设备驱动的艺术之旅 - 简单网卡驱动模型
- 1.21 多对多关系 (单向)
- Paint---FontMetrics
- 嵌入式微控制器(Microcontroller Unit, MCU) 与内存