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

链接: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. Android项目——短信发送器

    因为应用要使用手机的短信服务,所以要在清单文件AndroidManifest.xml中添加短信服务权限: <?xml version="1.0" encoding=" ...

  2. Spring源码学习之:你不知道的spring注入方式

    前言 在Spring配置文件中使用XML文件进行配置,实际上是让Spring执行了相应的代码,例如: 使用<bean>元素,实际上是让Spring执行无参或有参构造器 使用<prop ...

  3. Optimize Managed Code For Multi-Core Machines

    Parallel Performance Optimize Managed Code For Multi-Core Machines Daan Leijen and Judd Hall This ar ...

  4. Qt QTreeWidget节点的添加+双击响应+删除详解(转)

    QTreeWidget是实现树形结构的类,在很多软件中都可以看到类似树形结构的界面. 我做的一个示例如下图,用来处理图像,最顶层节点是图像的路径名,子节点是图像的各个波段,双击各个波段会显示图像各波段 ...

  5. SVG中的'defs' and 'use'-可复用的图元定义

    在下一个示例中,我使用了defs中的元素之前,定义了如何去展现图元. <?xml version="1.0" standalone="no"?> & ...

  6. linux服务之ssh

    架构:c/s 开发语言:c语言 服务器端:在linux平台下部署 客户端:一般是cli界面下的ssh命令 官网:http://www.openssh.com/portable.html 25个必须记住 ...

  7. 【C语言模拟实现】浮点数-转-定点数

    要想超神,就要什么都精! 知识准备: 1. 输出浮点数的十六进制形式?(利用指针输出) 将浮点数指针-转换成-整型指针,以十六进制的格式输出指针内容. 示例程序: #include<stdio. ...

  8. node js 常用模块

    前100个依赖库里,underscore是属于语言基础类,express是服务器框架,有5.6个测试框架.以及5.6个递归遍历目录树的工具类.3个左右的命令行解析工具类,3个主流数据库的链接clien ...

  9. Sublime Text3注册码 (备用)

    复制如下三个任意一个正版注册码即可—– BEGIN LICENSE —–Andrew WeberSingle User LicenseEA7E-855605813A03DD 5E4AD9E6 6C0E ...

  10. eclipse开发Android程序sdk和avd的图标不见了

    在eclipse中开发我们的Android程序时,安装sdk是必不可少的,有时候会出现sdk和avd的图标都不见了的情况,一般出现这种情况的原因是你从别处copy了一个sdk的包然后直接在引用造成的, ...