Description

「飞奔」快递公司成立之后,已经分别与市内许多中小企业公司签订邮件收送服务契约。由于有些公司是在同一栋大楼内,所以「飞奔」公司收件的地点(收件点)最多只有m点 (1, 2, …, m),因此「飞奔」仅先行采购了三辆货車并聘用了三名司机,每天早上分别从收件地点 「1」, 「2」 及 「3」出发。而在与客户的服务契约中有明确订约:「飞奔」必须在客户提出邮件寄送要求的隔天派人至该公司(地点)收件。 为了能更有效率的服务客户并节省收件时间,该公司设立了收件服务登记网站,客户如有邮件需要寄送,必须在需要收件的前一天就先上网登记。为了节省油量,「飞奔」就利用晚上先行安排三位司机隔天的收件路线。每位司机至各地点收件的顺序应与各公司上网登记的顺序相符且必须能在最省油的情况下完成当天所有的收件服务。因此每位司机有可能需要在不同时间重复到同一地点收件,或不同的司机有可能需在不同的时间点前往同一地点收件。 如下面范例二(收件公司地点依序为: 4 2 4 1 5 4 3 2 1)所示,虽然司机1一开始就已经在收件地点「1」了,但是他却不能先把后面第四个登记的公司(地点「1」)邮件先收了再前往第一、第二、或第三个登记收件地点(地点「4」,「2」,「4」)收件。但是如果前三个登记收件的服务是由司机2或3來负责,则司机1就可以在地点「1」收了第四个登记的邮件后再前往后面所登记的地点收件。此外,在某些情况下,不一定每辆车都要收到货,也就是說,最佳收件方式也有可能是只需出动一或兩辆车去收货。请写一个程序來帮「飞奔」公司计算每天依预约顺序至各收件地点收件的最少总耗油量。

Input

输入文件第一行有一个整数 m(3 < = m < = 200),代表「飞奔」公司收件的地点数,以1至m之间的整数代号來表示每个地点。 接下來的m行(第2到第m+1行),每行有m个整数,代表一个矩阵D。第 i +1行的第 j 个整数是D(i, j),D(i, j) 代表司机开车从收件点 i 到收件点 j 所需耗油量。最后有一行数串,数串之数字依序为前一天上网登记要求收件的公司地点代号,最多会有1000个收件请求。输入文件中任兩个相邻的整数都以一个空白隔开。 //D(i,j)<=maxint 注意:油量矩阵D满足三角不等式,也就是說 D(i, j) < = D(i, k) + D(k, j),1 < = i, j, k < = m。因此,每辆车前往下一个收件地点时一定是直接前往,不必先绕道至其它地点再抵达下个收件地点。

Output

输出一个整数,代表收件所需最少总耗油量。

Sample Input

4
0 5 0 6
6 0 5 6
1 6 0 6
1 1 1 0
1 1 1 1 4 4 2 2 2 3

Sample Output

6

样例说明:到每个请求收件地点的司机分别为1 1 1 1 3 3 2 2 2 1,因此司机1只需从起使点1移动到地点3,司机2只需停留在地点2,司机3从起始点3移动到地点4。

Solution

sbDP,基本相当于昨晚上nowcoder的弱化版
因为一个地方j和k写反调了半天……GG
考虑裸暴力,f[num][i][j][k]表示当前完成了第num个收件点,三辆车分别在ijk三个位置
很容易发现ijk可以优化掉一维因为一定有一辆车在上一个收件点a[num-1]
再滚动数组优化一下第一维就可以过了,f[0/1][i][j]表示一辆车在i,一辆在j。复杂度m*n^2

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N (205)
using namespace std;
int f[][N][N],dis[N][N],a[N*],n,m,x,pre=,now=;
int main()
{
memset(f,0x3f,sizeof(f));
scanf("%d",&n);
for (int i=; i<=n; ++i)
for (int j=; j<=n; ++j)
scanf("%d",&dis[i][j]);
while (scanf("%d",&x)!=EOF) a[++m]=x; f[][][]=f[][][]=dis[][a[]];
f[][][]=f[][][]=dis[][a[]];
f[][][]=f[][][]=dis[][a[]]; for (int i=; i<=m; ++i)
{
memset(f[now],0x3f,sizeof(f[now]));
for (int j=; j<=n; ++j)
for (int k=; k<=n; ++k)
{
f[now][j][k]=f[now][k][j]=min(f[now][j][k], f[pre][j][k]+dis[a[i-]][a[i]]);
f[now][a[i-]][j]=f[now][j][a[i-]]=min(f[now][j][a[i-]], f[pre][j][k]+dis[k][a[i]]);
f[now][a[i-]][k]=f[now][k][a[i-]]=min(f[now][k][a[i-]], f[pre][j][k]+dis[j][a[i]]);
}
pre^=; now^=;
} int ans=0x7fffffff;
for (int i=; i<=n; ++i)
for (int j=; j<=n; ++j)
ans=min(ans,f[pre][i][j]);
printf("%d",ans);
}

最新文章

  1. Windows Azure - Troubleshooting &amp; Debugging: Role Recycling
  2. 写 test-case心得
  3. .net常用组件
  4. hdu 4259 Double Dealing
  5. Project Euler 110:Diophantine reciprocals II 丢番图倒数II
  6. C++ 中的 const 详解
  7. window.event对象详细介绍
  8. asp.net core导入excel
  9. layabox typescript 安装固定版本
  10. Django 学习手册 - 下载数据库表格(XLS/CSV)
  11. EasyUI Combobox 设置默认值
  12. 彻底了解 suid, sgid ,sticky权限
  13. 机器学习: K-means 聚类
  14. apache airflow docker 运行简单试用
  15. JAVA—Filter
  16. 应用层-Http/Https
  17. Mysql 源码编译安装 ( 5.5 、5.6 共存 )
  18. JavaMail 实现发送验证码,带验证码模板的
  19. 「学习记录」《数值分析》第三章计算实习题(Python语言)
  20. 《Python 机器学习》笔记(一)

热门文章

  1. Docker的学习笔记(开发的技术分享转发)
  2. 牛客网Java刷题知识点之为什么HashMap不支持线程的同步,不是线程安全的?如何实现HashMap的同步?
  3. 安装clouderamaner时出现Failed to detect distribution错误(在ubuntu14.04版本里)
  4. Java开发环境搭建——IntelliJ Idea开发环境
  5. unet知识点
  6. 温故而知新,再探ConcurrentHashMap
  7. Linux安装PHP加速器Xcache
  8. 如何给swing加上alt+x和ctrl+x快捷键
  9. Json/Xml简介和处理模型
  10. SelectedItems的用法讲解