CODEVS_2800 送外卖 状态压缩+动态规划
原题链接:http://codevs.cn/problem/2800/
有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上。n个不同的客户分别在1~n个编号的城市中。送外卖的从0号城市出发,然后n个城市都要走一次(一个城市可以走多次),最后还要回到0点(他的单位),请问最短时间是多少。现在已知任意两个城市的直接通路的时间。
第一行一个正整数n (1<=n<=15)
接下来是一个(n+1)*(n+1)的矩阵,矩阵中的数均为不超过10000的正整数。矩阵的i行j列表示第i-1号城市和j-1号城市之间直接通路的时间。当然城市a到城市b的直接通路时间和城市b到城市a的直接通路时间不一定相同,也就是说道路都是单向的。
一个正整数表示最少花费的时间
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
8
1<=n<=15
这道题很容易想到状压dp,首先跑一遍floyd求出各个点之间的最短路,然后dp。
状态是dp[i][j]表示状态为i(二进制,表示是否访问过每个点),在位置j时的最短路。
转移就是:dp[i][j]=min(dp[i-(1<<v)][u]+grid[u][v],dp[i][j]),其中v是当前位置,u是上一个状态的位置。
需要注意的是dp的顺序应该是由含1的个数少的二进制到1的个数高的二进制;由于最开始就在0位置,所以dp[(1<<n)-1][0]不可能被转移到,所以最后的答案应该是ans=min(ans,dp[(1<<n)-1][i]+grid[i][0]),其中0<=i<n。
详见代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstdio>
#include<climits>
#define INF INT_MAX
#define MAX_S 1<<16
#define MAX_N 17
using namespace std; struct node
{
int val,num;
node(int v,int n)
{val=v;num=n;}
node(){}
}; node one[MAX_S];
int grid[MAX_N][MAX_N];
int n;
int dp[MAX_S][MAX_N];
int numOfOne(int x)
{
int res=0;
for(int i=0;i<n;i++)
if((x>>i)&1)res++;
return res;
} void floyd()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
grid[i][j]=min(grid[i][j],grid[i][k]+grid[k][j]);
} bool cmp(node a,node b)
{
return a.num<b.num;
} int main()
{
scanf("%d",&n);
n++;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&grid[i][j]);
int totS=1<<n;
for(int i=0;i<totS;i++)one[i]=node(i,numOfOne(i)); for(int i=0;i<totS;i++)
for(int j=0;j<n;j++)
dp[i][j]=INF; floyd();
sort(one,one+totS,cmp);
dp[1][0]=0;
for(int i=0;i<totS;i++)
{
int s=one[i].val;
for(int v=0;v<n;v++)
{
if(!((s>>v)&1))continue;
int t=s-(1<<v);
int tmp=INF;
for(int u=0;u<n;u++)
{
if((!((t>>u)&1))||dp[t][u]==INF)continue;
tmp=min(tmp,dp[t][u]+grid[u][v]);
}
if(tmp!=INF)
dp[s][v]=tmp;
}
}
int ans=INF;
for(int i=0;i<n;i++)
ans=dp[totS-1][i]==INF?ans:min(ans,dp[totS-1][i]+grid[i][0]);
cout<<ans<<endl;
return 0;
}
CODEVS_2800 送外卖 状态压缩+动态规划的更多相关文章
- Codeves 2800 送外卖 状态压缩DP+floyd
送外卖 题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后 ...
- 2800 送外卖[状态压缩dp]
2800 送外卖 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有一个送外卖的,他手上有n份订单,他 ...
- BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划
BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- 状态压缩动态规划(状压DP)详解
0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...
- poj 3254(状态压缩+动态规划)
http://poj.org/problem?id=3254 题意:有一个n*m的农场(01矩阵),其中1表示种了草可以放牛,0表示没种草不能放牛,并且如果某个地方放了牛,它的上下左右四个方向都不能放 ...
- 【学术篇】状态压缩动态规划——POJ3254/洛谷1879 玉米田Corn Field
我要开状压dp的坑了..直播从入门到放弃系列.. 那就先拿一道状压dp的水题练练手吧.. 然后就找到了这一道..这道题使我清醒地认识到阻碍我的不是算法,而是视力= = 传送门: poj:http:// ...
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1087 题意概括 在n*n的棋盘上面放k个国王,使得他们互相无法攻击,问有多少种摆法. 题解 dp[ ...
- BZOJ1076 [SCOI2008]奖励关 概率 状态压缩动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1076 题意概括 有n个东西,k次扔出来.每次等概率扔出其中一个. 你可以拿这个东西,但是有条件,得 ...
随机推荐
- shell脚本,打印九九乘法表。
[root@localhost ~]# .sh #!/bin/bash #计算九九乘法表 ` do ` do [ $j -le $i ] && echo -n "$i*$j= ...
- 【Linux命令大全】
Linux常用命令大全 系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部 ...
- 嵌入式之:Linux下文件编译过程
本文主要三个部分:1.GNU GCC简介 2.C/C++交叉编译器arm-elf-gcc 3.make文件,用于工程管理 部分一:GNU GCC简介: 该编译器基本功能: (1)输出预处理后的文件(展 ...
- POJ:3461-Oulipo(KMP模板题)
原题传送:http://poj.org/problem?id=3461 Oulipo Time Limit: 1000MS Memory Limit: 65536K Description The F ...
- cf 1016D
D. Vasya And The Matrix time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- slave_net_timeout 问题一则
[背景] 对一套数据库集群进行5.5升级到5.6之后,alter.log 报warning异常. 2015-02-03 15:44:51 19633 [Warning] Storing MySQL ...
- Linux下二进制文件安装MySQL
MySQL 下载地址:https://dev.mysql.com/downloads/mysql/ 并按如下方式选择来下载安装包. 1. 设置配置文件/etc/my.cnmore /etc/my.cn ...
- 面试准备——rpc面试题
https://www.jianshu.com/p/28e48e5f9c73 1 什么是 RPC ? RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方 ...
- c++ - 在终端中,cout不显示任何内容
g++ 是一个编译器,它将源代码转换成可以执行程序,但不运行它. 你必须亲自运行程序. g++ 生成的程序的默认名称是 a.out ( 因为历史原因),因此你将运行它作为 $./a.out 如果要 ...
- CF802D
D. Marmots (easy) time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...