POJ 3311 Hie with the Pie(Floyd+状态压缩DP)
题是看了这位的博客之后理解的,只不过我是又加了点简单的注释。
链接:http://blog.csdn.net/chinaczy/article/details/5890768
我还加了一些注释代码,对于新手的我,看起来可能更方便些吧,顺便说下快捷键
先选中要操作的行,ctrl+shift+c 是注释 ctrl+shift+x是解注释(cb的快捷键)
/*
Floyd + 状态压缩DP
题意是有N个城市(1~N)和一个PIZZA店(0),要求一条回路,从0出发,又回到0,而且距离最短
也就是TSP(旅行商)问题,首先不难想到用FLOYD先求出任意2点的距离dis[i][j]
接着枚举所有状态,用11位二进制表示10个城市和pizza店,1表示经过,0表示没有经过
定义状态DP(S,i)表示在S状态下,到达城市I的最优值
接着状态转移方程:DP(S,i) = min{DP(S^(1<<i-1),k) + dis[k][j],DP(S,i)},其中S^(1<<i-1)表示未到达城市i的所有状态,1<=k<=n
对于全1的状态,即S = (1<<n)-1则表示经过所有城市的状态,最终还需要回到PIZZA店0
那么最终答案就是min{DP(S,i) + dis[i][0]} TSP是NP困难问题,所以地图必须要小,本题是10,所以也可以根据这个想到floyd,(时间复杂度n^3)和状压dp (用二进制存10位,且只有2个状态,走过,没走过)
*/
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 100000000
using namespace std;
int dis[12][12];
int dp[1<<11][12];
int n,ans,_min;
int main()
{
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Zmy\\Desktop\\in.txt","r",stdin);//这应该修改下重定向的文件路径
// freopen("C:\\Users\\Zmy\\Desktop\\out.txt","w",stdout);
#endif // ONLINE_JUDGE
while(scanf("%d",&n) && n)
{
/**< 输入 */
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= n; ++j)
scanf("%d",&dis[i][j]); // puts("before");
// for(int i = 0; i <= n; ++i)
// {
// for(int j = 0; j <= n; ++j)
// printf("%3d ",dis[i][j]);
// puts("");
// } /**< 这段用弗洛伊德求出了从i点到各个j点的最短距离 存在了dis中,即更新了dis */
for(int k = 0; k <= n; ++k)
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= n; ++j)
if(dis[i][k] + dis[k][j] < dis[i][j])
dis[i][j] = dis[i][k] + dis[k][j]; // puts("after");
// for(int i = 0; i <= n; ++i)
// {
// for(int j = 0; j <= n; ++j)
// printf("%3d ",dis[i][j]);
// puts("");
// } for(int S = 0; S < (1<<n); ++S) //枚举所有状态,用位运算表示
for(int i = 1; i <= n; ++i)
{
if(S & (1<<(i-1)))//状态S中已经过城市i
{ /**< 注意:DP的边界是这句话,好牛逼!! */
if(S == (1<<(i-1))) dp[S][i] = dis[0][i];//状态S只经过城市I,最优解自然是从0出发到i的dis,这也是DP的边界 //如果S有经过多个城市
else
{
dp[S][i] = INF; //枚举不是城市I的其他城市
for(int j = 1; j <= n; ++j)
{
//在没经过城市I的状态中,寻找合适的中间点J使得距离更短,和FLOYD一样
if(S & (1<<(j-1)) && j != i)
dp[S][i] = min(dp[S^(1<<(i-1))][j] + dis[j][i],dp[S][i]);
} }
}
}
ans = dp[(1<<n)-1][1] + dis[1][0];
for(int i = 2; i <= n; ++i)
if(dp[(1<<n)-1][i] + dis[i][0] < ans)
ans = dp[(1<<n)-1][i] + dis[i][0];
printf("%d\n",ans);
}
return 0;
}
POJ 3311 Hie with the Pie(Floyd+状态压缩DP)的更多相关文章
- poj 3311 Hie with the Pie(状态压缩dp)
Description The Pizazz Pizzeria prides itself or more (up to ) orders to be processed before he star ...
- [poj3311]Hie with the Pie(Floyd+状态压缩DP)
题意:tsp问题,经过图中所有的点并回到原点的最短距离. 解题关键:floyd+状态压缩dp,注意floyd时k必须在最外层 转移方程:$dp[S][i] = \min (dp[S \wedge (1 ...
- POJ 3311 Hie with the Pie floyd+状压DP
链接:http://poj.org/problem?id=3311 题意:有N个地点和一个出发点(N<=10),给出全部地点两两之间的距离,问从出发点出发,走遍全部地点再回到出发点的最短距离是多 ...
- POJ 3311 Hie with the Pie(状压DP + Floyd)
题目链接:http://poj.org/problem?id=3311 Description The Pizazz Pizzeria prides itself in delivering pizz ...
- POJ 3311 Hie with the Pie (状压DP)
题意: 每个点都可以走多次的TSP问题:有n个点(n<=11),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短是多少? 思路: 同HDU 5418 VICTOR AND WORL ...
- [POJ 3311]Hie with the Pie——谈论TSP难题DP解决方法
主题连接: id=3311">http://poj.org/problem?id=3311 题目大意:有n+1个点,给出点0~n的每两个点之间的距离,求这个图上TSP问题的最小解 ...
- POJ 3311 Hie with the Pie 【状压DP】
Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possi ...
- poj 3311 Hie with the Pie (状压dp) (Tsp问题)
这道题就是Tsp问题,稍微加了些改变 注意以下问题 (1)每个点可以经过多次,这里就可以用弗洛伊德初始化最短距离 (2)在循环中集合可以用S表示更清晰一些 (3)第一维为状态,第二维为在哪个点,不要写 ...
- POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)
题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...
随机推荐
- php parse_url 函数教程
[导读] php parse_url 函数教程parse_url ( PHP 4中, PHP 5中) parse_url -解析URL并返回其组成部分 描述 混合parse_url (字符串$网址[摘 ...
- MySQL 常用show命令
MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- c# 加密转载 备忘
public sealed class EncryptUtils { #region Base64加密解密 /// <summary> /// Base64加密 /// </summ ...
- 在EDIUS中调整素材颜色的方法
EDIUS是一款非线性编辑软件,有很强大的视频剪辑功能,很受学习视频剪辑的同学欢迎.本EDIUS教程今天的主要目的就是分享自己学习经验写了一篇EDIUS入门教程文章,希望能给学习EDIUS的小伙伴带来 ...
- 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误
当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示. 有两种方法可以解决以上问题: 1.修改we ...
- Python_Day_4(内置函数之篇)
一:内置函数 常用内置函数如下: 1)abs:取一个数字的绝对值 #abs:取绝对值n = abs(-10)print(n) 2)any和all 值为Fslse有:0,None,"" ...
- Oracle数据库—— 事务处理与并发控制
一.涉及内容 1.理解事务的概念和几个特性. 2.熟练掌握事务管理命令的使用. 3.理解并发操作的概念和数据库锁的类型. 二.具体操作 (12.5 实验) 1. 分析以下代码,说出代码中的哪些部分体现 ...
- maven项目依赖小试牛刀
1.先建立空的wbh-parent,留下pom.xml;将项目中用的jar包依赖全放进去: 2.建立core项目,当然全是maven的,这个建好后,是用来让其他项目引用的,所以必须用maven ins ...
- mysql 远程访问
如何开启MySQL的远程帐号-1)首先以 root 帐户登陆 MySQL 在 Windows 主机中点击开始菜单,运行,输入“cmd”,进入控制台,然后cd 进入MySQL 的 bin 目录下,然后输 ...
- 编译工程时报illegal character:\65279--转
windows对UTF-8文件进行了特殊处理,对UTF-8的文本文件自动在前面加了三个byte(EF BB BF),javac编译时,读到最前面这三个byte时报错 illegal character ...