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 ...
随机推荐
- 【html】标签的分类
一.标签的分类 1. 块状元素 : 独占一行, 宽高,行高,顶底部边距都可以进行设置 <div> <p> <h1-h6> <ol> <ul> ...
- 2991:2011 求2011^n的后四位。
2991:2011 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 已知长度最大为200位的正整数n,请求出2011^n的后四位. 输入 第一行为一个正整数k ...
- .net core中使用缓存(cache)
官方文档:https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.2#use ...
- C#数组 修改
今天咱们了解下C#中的数组 后面会讲到集合.泛型集合 咱们分开来讲,免得出现混乱 讲完这三个,咱们再汇总一下,看看有什共同点和不同点 定义一个数组: ]; , , , , , , , , , }; 两 ...
- ARP 地址分类 NAT技术
第1章 OSI回顾 1.1 TCP/IP协议族组成 应用层 主机到主机层 互联网层 网络接入层 1.2 总结应用层掌握的协议与端口号对应关系 http(80) telnet(23) ftp(2 ...
- node.js学习笔记(一)——创建第一个应用
巧妇难为无米之炊.要学习node.js,当然必须先有node.js环境(可以去官网 http://nodejs.cn/ 下载安装),如果还是不懂怎么配置开发环境,度娘会告诉你一切. 安装完成环境之后, ...
- Python浮点算术:争议和限制
浮点数在计算机硬件中表示为以 2 为基数(二进制)的小数.举例而言,十进制的小数 0.125 等于 1/10 + 2/100 + 5/1000 ,同理,二进制的小数 0.001 等于0/2 + 0/4 ...
- NAT概念解释(不完全版,但不会搞错...)
NAT在计算器网络中,网络地址转换(Network Address Translation,缩写为NAT),也叫做网络掩蔽或者IP掩蔽(IP masquerading)是一种IP数据包在通过路由器或防 ...
- 戴尔win10重新安装win7系统
戴尔v5468电脑win10重装回win7系统 首先是公司需要用到ie8来执行公司的项目维护,都是很早之前的项目了,因为是对接政府相关的业务,不怎么有把握对项目进行稳定更新,所以我就为这个ie8操碎了 ...
- 【树莓派】crontab的两个问题
1,/var/log下面,没有cron.log日志 root@raspberrypi:/# nano /etc/rsyslog.conf …… …… ############### #### RULE ...