bzoj千题计划201:bzoj1820: [JSOI2010]Express Service 快递服务

http://www.lydsy.com/JudgeOnline/problem.php?id=1820

很容易想到dp[i][a][b][c] 到第i个收件地点,三个司机分别在a,b,c 收件地点的最少耗油量

枚举第i个收件地点有哪个司机过来转移

N*M*M*M= 8e9 TLE&&MLE

压去一维,到第i个收件地点,一定有一个司机在第i个收件地点

N*M*M=4e7  MLE

滚动数组滚掉第一维

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

#define M 201

int dis[M][M];
int dp[2][M][M];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); }
}

int main()
{
    int m;
    read(m);
    for(int i=1;i<=m;++i)
        for(int j=1;j<=m;++j)
            read(dis[i][j]);
    int x,last;
    read(last);
    memset(dp[0],63,sizeof(dp[0]));
    int inf=dp[0][0][0];
    dp[0][2][3]=dis[1][last];
    dp[0][1][3]=dis[2][last];
    dp[0][1][2]=dis[3][last];
    int u=1,v=0;
    while(scanf("%d",&x)!=EOF)
    {
        swap(u,v);
        memset(dp[v],63,sizeof(dp[v]));
        for(int i=1;i<=m;++i)
            for(int j=i;j<=m;++j)
                if(dp[u][i][j]!=inf)
                {
                    dp[v][i][j]=min(dp[v][i][j],dp[u][i][j]+dis[last][x]);
                    dp[v][min(last,j)][max(last,j)]=min(dp[v][min(last,j)][max(last,j)],dp[u][i][j]+dis[i][x]);
                    dp[v][min(last,i)][max(last,i)]=min(dp[v][min(last,i)][max(last,i)],dp[u][i][j]+dis[j][x]);
                }
        last=x;
    }
    int ans=inf;
    for(int i=1;i<=m;++i)
        for(int j=i;j<=m;++j)
            ans=min(ans,dp[v][i][j]);
    cout<<ans;
}

1820: [JSOI2010]Express Service 快递服务

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1118  Solved: 482
[Submit][Status][Discuss]

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。

HINT

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8227379.html

时间: 2024-10-12 10:44:28

bzoj千题计划201:bzoj1820: [JSOI2010]Express Service 快递服务的相关文章

[bzoj1820][JSOI2010][Express Service 快递服务] (动态规划)

Description 「飞奔」快递公司成立之后,已经分别与市内许多中小企业公司签订邮件收送服务契约.由于有些公司是在同一栋大楼内,所以「飞奔」公司收件的地点(收件点)最多只有m点 (1, 2, …, m),因此「飞奔」仅先行采购了三辆货車并聘用了三名司机,每天早上分别从收件地点 「1」, 「2」 及 「3」出发.而在与客户的服务契约中有明确订约:「飞奔」必须在客户提出邮件寄送要求的隔天派人至该公司(地点)收件. 为了能更有效率的服务客户并节省收件时间,该公司设立了收件服务登记网站,客户如有邮件

1820: [JSOI2010]Express Service 快递服务

1820: [JSOI2010]Express Service 快递服务 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 847  Solved: 325[Submit][Status] Description 「飞奔」快递公司成立之后,已经分别与市内许多中小企业公司签订邮件收送服务契约.由于有些公司是在同一栋大楼内,所以「飞奔」公司收件的地点(收件点)最多只有m点 (1, 2, …, m),因此「飞奔」仅先行采购了三辆货車并聘用了三名司机,每天早上

bzoj千题计划185:bzoj1260: [CQOI2007]涂色paint

http://www.lydsy.com/JudgeOnline/problem.php?id=1260 区间DP模型 dp[l][r] 表示涂完区间[l,r]所需的最少次数 从小到大们枚举区间[l,r] 如果col[l]==col[r] dp[l][r]=min(dp[l+1][r],dp[l][r-1],dp[l+1][r-1]+1) 否则 dp[l][r]=min(dp[l][k]+dp[k+1][r]) 我还是辣鸡啊~~~~(>_<)~~~~,这种题都不能秒 #include<c

bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len [i] 表示以i结尾的最长不下降子序列的长度 pre_sum[i] 表示对应长度下的方案数 suf_len[i] 表示以i开头的最长不下降子序列长度 suf_sum[i] 表示对应长度下的方案数 若已有了这4个数组 设最长上升子序列长度=mx 那么 如果pre_len[i]+suf_len[i] -

bzoj千题计划304:bzoj3676: [Apio2014]回文串

https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 300001 char ss[N]; int s[N]; int tot=1,last; int fail[N],len

bzoj千题计划106:bzoj1014 [JSOI2008]火星人prefix

http://www.lydsy.com/JudgeOnline/problem.php?id=1014 两个后缀的最长公共前缀:二分+hash 带修改带插入:splay维护 #include<cstdio> #include<cstring> #include<iostream> #define L 100001 typedef unsigned long long ULL; using namespace std; char s[L+4]; int tot,root

bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic

http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 用b数组表示 节点第0/1行的最右一列是否连接了右边 来 辅助 节点的合并 查询 对两个点位于矩形的位置分4种情况讨论 两点是否联通,要考虑四种情况 (以两个位置是矩形左上角和右上角为例) 1.直接联通,线段树的节点包含了这种情况,直接判断 2. 3. 4. 后三种情况需要再查询[1,l]和[r,n

bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔

http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] 表示 从i号柱子 上把j个盘子移到 g[i][j] 柱子上的步数 初始化:f[0][1]=1,g[0][1] 根据优先级决定 设三根柱子分别为0,1,2 对于每一个f[x][i], 把前i-1个移走,把第i个移走,把前i-1个移回 令y=g[x][i-1],则k=0+1+2-x-y 我们希望 把i-

bzoj千题计划111:bzoj1021: [SHOI2008]Debt 循环的债务

http://www.lydsy.com/JudgeOnline/problem.php?id=1021 如果A收到了B的1张10元,那么A绝对不会把这张10元再给C 因为这样不如B直接给C优 由此可以推出 若A欠B20元,B欠C 30元, 那么A还C20元,B还C10元最优 所以一共只有 A->BC   B->AC  C->AB AB->C  BC->A  AC->B 这6种转移情况 根据输入,我们可以知道三人最终手中有多少钱ea.eb.ec,一共有多少钱sum 设f