poj 3311(状态压缩DP)
poj 3311(状态压缩DP)
题意:一个人送披萨从原点出发,每次不超过10个地方,每个地方可以重复走,给出这些地方之间的时间,求送完披萨回到原点的最小时间。
解析:类似TSP问题,但是每个点可以重复走,先用floyd预处理每个点两两之间的最短距离,然后用状态压缩DP求出走完所有点后回到原点的最短距离,用一个二进制数表示城市是否走过。
状态表示:dp[i][j]表示到达j点状态为i的最短距离
状态转移方程:dp[i][j]=min(dp[i][j],dp[j'][k]+dis[k][j]),dis[k][j]为k到j的最短距离,dp[j'][k]为到达k的没经过j所有状态的最短距离
DP边界条件:dp[i][j]=dp[0][i],i是只经过j的状态
枚举所有的状态,求解dp[i][j],然后再枚举走完所有的地方后的状态,求min(dp[(1<<n)-1][j]+dis[j][0])就行了
AC代码如下:
#include<stdio.h>
#define INF 0x7fffffff
int dp[<<][],n,dis[][];
void floyd()
{
int i,j,k;
for(k=;k<=n;k++)
for(i=;i<=n;i++)
for(j=;j<=n;j++)
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
int min(int a,int b)
{
return a<b?a:b;
}
void DP()
{
int i,j,k;
for(i=;i< (<<n);i++) //枚举所有的状态
{
for(j=;j<=n;j++)
if(i==(<<(j-))) //状态i中只走过城市j
dp[i][j]=dis[][j];
else
{
if(i&(<<(j-))) //状态i中走过城市j和其他城市
{
dp[i][j]=INF;
for(k=;k<=n;k++)
{
if(j!=k && (i&(<<(k-)))) //枚举不是城市j的其他城市
//在没经过城市j的状态中,寻找合适的中间点k使得距离更短
dp[i][j]=min(dp[i][j],dp[i^(<<(j-))][k]+dis[k][j]);
}
}
}
}
int ans=INF;
for(i=;i<=n;i++) //枚举走完所有城市的状态,求回到原点的最短的距离
ans=min(ans,dp[(<<n)-][i]+dis[i][]);
printf("%d\n",ans);
}
int main()
{
int i,j;
while(scanf("%d",&n)&&n)
{
for(i=;i<=n;i++)
for(j=;j<=n;j++)
scanf("%d",&dis[i][j]);
floyd(); //预处理求出每个点两两之间的最短距离
DP();
}
return ;
}
poj 3311(状态压缩DP)的更多相关文章
- POJ 1185 状态压缩DP(转)
1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...
- POJ 1185 状态压缩DP 炮兵阵地
题目直达车: POJ 1185 炮兵阵地 分析: 列( <=10 )的数据比较小, 一般会想到状压DP. Ⅰ.如果一行10全个‘P’,满足题意的状态不超过60种(可手动枚举). Ⅱ.用DFS ...
- poj 2923(状态压缩dp)
题意:就是给了你一些货物的重量,然后给了两辆车一次的载重,让你求出最少的运输次数. 分析:首先要从一辆车入手,搜出所有的一次能够运的所有状态,然后把两辆车的状态进行合并,最后就是解决了,有两种方法: ...
- poj 2688 状态压缩dp解tsp
题意: 裸的tsp. 分析: 用bfs求出随意两点之间的距离后能够暴搜也能够用next_permutation水,但效率肯定不如状压dp.dp[s][u]表示从0出发訪问过s集合中的点.眼下在点u走过 ...
- Mondriaan's Dream(POJ 2411状态压缩dp)
题意:用1*2的方格填充m*n的方格不能重叠,问有多少种填充方法 分析:dp[i][j]表示i行状态为j时的方案数,对于j,0表示该列竖放(影响下一行的该列),1表示横放成功(影响下一列)或上一列竖放 ...
- poj 2411 状态压缩dp
思路:将每一行看做一个二进制位,那么所有的合法状态为相邻为1的个数一定要为偶数个.这样就可以先把所有的合法状态找到.由于没一层的合法状态都是一样的,那么可以用一个数组保存.由第i-1行到第i行的状态转 ...
- poj 3254 状态压缩DP
思路:把每行的数当做是一个二进制串,0不变,1变或不变,找出所有的合法二进制形式表示的整数,即相邻不同为1,那么第i-1行与第i行的状态转移方程为dp[i][j]+=dp[i-1][k]: 这个方程得 ...
- POJ 3254 状态压缩 DP
B - Corn Fields Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:65536KB ...
- poj 3311 floyd+dfs或状态压缩dp 两种方法
Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6436 Accepted: 3470 ...
随机推荐
- 3235: [Ahoi2013]好方的蛇
3235: [Ahoi2013]好方的蛇 链接 分析: 可以求出以每个点为顶点的满足条件的矩形有多少个,单调栈求.设为sum. 然后对这个数组进行二维前缀和,可以求出每个矩阵内,以右下角.左下角为端点 ...
- selenium 定位不到元素总结
元素在网页上,却会出现定位不到的情况的分析. 1. 定位不正确. 2. 页面还没有加载完就去查找元素了. 3. 有遮罩层. 首先说下第3点. 先前在公司遇到过这样的问题. 页面是显示出来了, 这个元素 ...
- 【Apache】 ab进行压力测试
前言: ab是apache自带的压力测试工具,当安装完apache的时候,就可以在bin下面找到ab然后进行apache 负载压力测试. 工具: Apache ab压测工具 一.安装 (1) 下载 : ...
- Linux命令应用大词典-第1章 登录、退出、关机和重启
1.1 login:用户登录系统 1.2 logout:退出登录shell 1.3 nologin:限制用户登录 1.4 exit:退出shell 1.5 sulogin:单用户登录(single u ...
- php js css加载合并函数 宋正河整理
<?php //php js css加载合并函数 宋正河整理 //转载请注明出处 define('COMBINE_JS',true); define('COMBINE_CSS',true); ...
- Java 浅拷贝 深拷贝
两者区别主要在于引用数据类型的属性,对于基本数据类型采用的是值传递,所以两者一样: 对于浅拷贝,引用数据类型只会进行引用传递,即复制一份引用值(内存地址)给新对象,一个对象的变化会影响到另一个的引用属 ...
- Netty源码分析第4章(pipeline)---->第4节: 传播inbound事件
Netty源码分析第四章: pipeline 第四节: 传播inbound事件 有关于inbound事件, 在概述中做过简单的介绍, 就是以自己为基准, 流向自己的事件, 比如最常见的channelR ...
- Netty源码分析第5章(ByteBuf)---->第5节: directArena分配缓冲区概述
Netty源码分析第五章: ByteBuf 第五节: directArena分配缓冲区概述 上一小节简单分析了PooledByteBufAllocator中, 线程局部缓存和arean的相关逻辑, 这 ...
- gcc 与 g++的区分较
一:gcc与g++比较 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为 ...
- 如何配置php客户端(phpredis)并连接Redis--华为DCS for Redis使用经验系列
使用php连接Redis.Memcache等都需要进行扩展,以CentOS为例,介绍phpredis的客户端环境搭建. 第0步:准备工作 华为云上购买1台弹性云服务器ECS(我选了CentOS 6.3 ...