题是看了这位的博客之后理解的,只不过我是又加了点简单的注释。

链接: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)的更多相关文章

  1. poj 3311 Hie with the Pie(状态压缩dp)

    Description The Pizazz Pizzeria prides itself or more (up to ) orders to be processed before he star ...

  2. [poj3311]Hie with the Pie(Floyd+状态压缩DP)

    题意:tsp问题,经过图中所有的点并回到原点的最短距离. 解题关键:floyd+状态压缩dp,注意floyd时k必须在最外层 转移方程:$dp[S][i] = \min (dp[S \wedge (1 ...

  3. POJ 3311 Hie with the Pie floyd+状压DP

    链接:http://poj.org/problem?id=3311 题意:有N个地点和一个出发点(N<=10),给出全部地点两两之间的距离,问从出发点出发,走遍全部地点再回到出发点的最短距离是多 ...

  4. POJ 3311 Hie with the Pie(状压DP + Floyd)

    题目链接:http://poj.org/problem?id=3311 Description The Pizazz Pizzeria prides itself in delivering pizz ...

  5. POJ 3311 Hie with the Pie (状压DP)

    题意: 每个点都可以走多次的TSP问题:有n个点(n<=11),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短是多少? 思路: 同HDU 5418 VICTOR AND WORL ...

  6. [POJ 3311]Hie with the Pie——谈论TSP难题DP解决方法

    主题连接:  id=3311">http://poj.org/problem?id=3311 题目大意:有n+1个点,给出点0~n的每两个点之间的距离,求这个图上TSP问题的最小解 ...

  7. POJ 3311 Hie with the Pie 【状压DP】

    Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possi ...

  8. poj 3311 Hie with the Pie (状压dp) (Tsp问题)

    这道题就是Tsp问题,稍微加了些改变 注意以下问题 (1)每个点可以经过多次,这里就可以用弗洛伊德初始化最短距离 (2)在循环中集合可以用S表示更清晰一些 (3)第一维为状态,第二维为在哪个点,不要写 ...

  9. POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)

    题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...

随机推荐

  1. php parse_url 函数教程

    [导读] php parse_url 函数教程parse_url ( PHP 4中, PHP 5中) parse_url -解析URL并返回其组成部分 描述 混合parse_url (字符串$网址[摘 ...

  2. MySQL 常用show命令

    MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  3. c# 加密转载 备忘

    public sealed class EncryptUtils { #region Base64加密解密 /// <summary> /// Base64加密 /// </summ ...

  4. 在EDIUS中调整素材颜色的方法

    EDIUS是一款非线性编辑软件,有很强大的视频剪辑功能,很受学习视频剪辑的同学欢迎.本EDIUS教程今天的主要目的就是分享自己学习经验写了一篇EDIUS入门教程文章,希望能给学习EDIUS的小伙伴带来 ...

  5. 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误

    当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示. 有两种方法可以解决以上问题: 1.修改we ...

  6. Python_Day_4(内置函数之篇)

    一:内置函数 常用内置函数如下: 1)abs:取一个数字的绝对值 #abs:取绝对值n = abs(-10)print(n) 2)any和all 值为Fslse有:0,None,"" ...

  7. Oracle数据库—— 事务处理与并发控制

    一.涉及内容 1.理解事务的概念和几个特性. 2.熟练掌握事务管理命令的使用. 3.理解并发操作的概念和数据库锁的类型. 二.具体操作 (12.5 实验) 1. 分析以下代码,说出代码中的哪些部分体现 ...

  8. maven项目依赖小试牛刀

    1.先建立空的wbh-parent,留下pom.xml;将项目中用的jar包依赖全放进去: 2.建立core项目,当然全是maven的,这个建好后,是用来让其他项目引用的,所以必须用maven ins ...

  9. mysql 远程访问

    如何开启MySQL的远程帐号-1)首先以 root 帐户登陆 MySQL 在 Windows 主机中点击开始菜单,运行,输入“cmd”,进入控制台,然后cd 进入MySQL 的 bin 目录下,然后输 ...

  10. 编译工程时报illegal character:\65279--转

    windows对UTF-8文件进行了特殊处理,对UTF-8的文本文件自动在前面加了三个byte(EF BB BF),javac编译时,读到最前面这三个byte时报错 illegal character ...