【APIO2013】机器人

【BZOJ3205】【UOJ107】【APIO2013】机器人 【题目链接】BZOJUOJ【思路要点】补档博客,无题解。【代码】#include<bits/stdc++.h> using namespace std; #define MAXN 505 #define MAXC 10 #define MAXV 1000005 #define MAXQ 300005 #define INF 1e9 //0 - up; 1 - right; 2 - do... 阅读详情

时间限制 : 40000 MS 空间限制 : 165536 KB

问题描述

VRI(Voltron机器人学会)的工程师建造了n个机器人。任意两个兼容的机器人站在同一个格子时可以合并为一个复合机器人。

我们把机器人用1至n编号(1<=n<=9)。如果两个机器人的编号是连续的,那么它们是兼容的,可以合并成一个复合机器人。最初这n个机器人各自都只有唯一的编号。而一个由两个或以上的机器人合并构成的复合机器人拥有两个编号,分别是构成它的所有机器人中最小和最大的编号。

例如,2号机器人只可以与1号或3号机器人合并。若2号机器人与3号机器人合并,可构成编号为2-3的复合机器人。如果编号为2-3的复合机器人与编号为4-6的复合机器人合并,可构成编号为2-6的复合机器人。当所有机器人合并以后则构成1-n复合机器人。

工程师把这n个机器人放在了一个封闭的房间中,房间四周均是墙。该房间被划分成w*h个方格。有些方格有障碍物,机器人不可经过或停留;其余方格允许多个机器人停留,同时允许机器人经过。任何时候一个机器人只占用一个方格。初始时刻,所有机器人均在不同的方格中。

这些原始的机器人不会自发地移动。它们只有被工程师沿x轴或y轴推动后,才会沿推动的方向不断向前直线移动,直至碰到障碍物或墙停止移动。停止移动后,它会扫描当前的格子是否存在可以与它合并的机器人,如果有,则合并并继续检查,直至不能再合并为止。工程师只能沿水平向左、水平向右、竖直向上、竖直向下四个方向推动机器人,并且,在机器人尚未停止移动时,不允许推动其它机器人,因此任何时刻,房间中都只能有一个机器人移动,为了帮助机器人转向,工程师在一些格子中放置了转向器。具体地说,转向器分为顺时针转向器(右转器)和逆时针转向器(左转器),顺时针转向器可以使到达该格子的机器人沿顺时针方向转向90度;逆时针转向器可以使到达该格子的机器人沿逆时针方向转向90度。

现在,我们将告诉你初始时刻房间内的信息。请你计算工程师最少共计需要推动机器人多少次,才能把所有的 n个机器人全部合并(如果可能的话)。

输入格式

输入的第 1行包含 3个整数 n、w和 h,用空格隔开。 接下来的 h行描述初始时刻房间内的信息,每行包含w个字符。这w* h
字符中每一个表示房间中的一个格子,意义如下: ‘ 1’至‘9’:表示该方格中有一个机器人,编号为这个数字; ‘ x’:表示该方格有障碍物;
‘ A’:表示该方格中有一个逆时针转向器; ‘ C’:表示该方格中有一个顺时针转向器; ‘ .’:表示该方格为空地。

输出格式

输出仅一个整数,表示最少需要推动的次数。 若不能使所有机器人全部合并,输出-1。

样例输入

4 10 5
1………
AA…x4…
..A..x….
2….x….
..C.3.A…

样例输出

5

提示

样例解释: 第一步:向右推动3号机器人,当它碰到转向器后会向上继续移动,直至碰到墙壁停止移动。
第二步:向上推动4号机器人,当它碰到墙壁后停止移动,与3号机器人合并,构成3-4号机器人
第三步:向上推动2号机器人,当它碰到转向器后会向左移动,由于左侧为墙壁,故停留在原地。
第四步:向右推动2号机器人,由于它在一个转向器上,故它会向上移动,直至碰到墙壁停止移动,与1号机器人合并,构成1-2号机器人。
第五步:向左推动3-4号机器人,当它碰到墙壁后停止移动,与1-2号机器人合并,构成1-4号机器人。

数据范围

2<=n<=9,2<=w<=500且2<=h<=500

题解

一道斯坦纳树好题。特殊点数目很少,特殊点的连接变为了特殊点的移动而已。
本题必须要标号相邻的特殊点才能合并,因此设状态时不能再使用状态压缩。类比区间合并的状态,我们设状态:f[l][r][x][y]f[l][r][x][y],表示编号从l到r的机器人在(x,y)处合并的最优值。因此有转移方程:

f[l][r][x][y]=min(f[l][r][x][y],f[l][t][x][y]+f[t+1][r][x][y])f[l][r][x][y]=min(f[l][r][x][y],f[l][t][x][y]+f[t+1][r][x][y])
f[l][r][tx][ty]=min(f[l][r][tx][ty],f[l][r][x][y]+1)f[l][r][tx][ty]=min(f[l][r][tx][ty],f[l][r][x][y]+1)
前者直接区间合并,后者在SPFA中实现。
由于用到了SPFA转移状态,且本题机器人移动的方式十分特殊,因此我们需要处理处每个格子往四个方向出发到达的位置。我们用DFS对其进行处理,但复杂度爆炸。我们发现很多点最终的状态都是相同的(因为机器人一口气走到底),因此可以用记忆化剪枝,特判一下转向器的情况。
然而这样以后还是过不了本题,因为会卡SPFA。这里用到了一个特殊的优化,我们按ff值的大小对状态排序(推荐桶排序)后放入队列q1中,松弛扩展出的点放入q2q2,这样两个队列中的值都是由小到大排列的(有优先队列的功效),每次松弛时从两个队列前端取出最小的一个值。这样避免了很多重复的讨论。
更多细节见代码。

代码

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef pair<int,int> pii;
const int inf=1e9;
int n,h,w,ans=inf,tot,maxx,cnt[505*505];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int f[10][10][505][505];
pii v[505*505],q[505*505],map[505][505][4];
bool flag[505][505][4],mark[505][505];
char G[505][505];
queue<pii> q1,q2;
pii DFS(int x,int y,int z)
{
    if(flag[x][y][z]) return map[x][y][z];
    flag[x][y][z]=true;
    int i=z;
    if(G[x][y]=='A') i=(i+3)%4;
    else if(G[x][y]=='C') i=(i+1)%4;
    int tx=dx[i]+x,ty=dy[i]+y;
    if(tx>=1&&tx<=h&&ty>=1&&ty<=w&&G[tx][ty]!='x') map[x][y][z]=DFS(tx,ty,i);
    else map[x][y][z]=make_pair(x,y);
    return map[x][y][z];
}
void spfa(int l,int r)
{
    for(int i=0;i<=maxx;i++) cnt[i]=0;
    for(int i=1;i<=tot;i++) cnt[f[l][r][v[i].first][v[i].second]]++;
    for(int i=1;i<=maxx;i++) cnt[i]+=cnt[i-1];
    for(int i=tot;i;i--) q[cnt[f[l][r][v[i].first][v[i].second]]--]=v[i];
    for(int i=1;i<=tot;i++) q2.push(q[i]);
    while(!q2.empty()||!q1.empty())
    {
        int x,y;
        if(q1.empty()) x=q2.front().first,y=q2.front().second,q2.pop();
        else if(q2.empty())
        {
            x=q1.front().first,y=q1.front().second;
            q1.pop(),mark[x][y]=false;
        }
        else if(f[l][r][q2.front().first][q2.front().second]<f[l][r][q1.front().first][q1.front().second])
        {
            x=q2.front().first,y=q2.front().second,q2.pop();
        }
        else
        {
            x=q1.front().first,y=q1.front().second;
            q1.pop(),mark[x][y]=false;
        }
        for(int i=0;i<4;i++)
        {
            int tx=map[x][y][i].first,ty=map[x][y][i].second;
            if(f[l][r][x][y]+1<f[l][r][tx][ty])
            {
                f[l][r][tx][ty]=f[l][r][x][y]+1;
                if(!mark[tx][ty]) mark[tx][ty]=true,q1.push(make_pair(tx,ty));
            }
        }
    }
}
int main()
{
    memset(f,0x3f,sizeof(f));
    scanf("%d%d%d",&n,&w,&h);
    for(int i=1;i<=h;i++) scanf("%s",G[i]+1);
    for(int i=1;i<=h;i++)
        for(int j=1;j<=w;j++)
            if(G[i][j]>=48&&G[i][j]<=57) f[G[i][j]-48][G[i][j]-48][i][j]=0;
    for(int i=1;i<=h;i++)
        for(int j=1;j<=w;j++)
            for(int k=0;k<4;k++)
                if(!flag[i][j][k]) map[i][j][k]=DFS(i,j,k);
    for(int k=1;k<=n;k++)
        for(int i=1;i+k-1<=n;i++)
        {
            int j=i+k-1;tot=maxx=0;
            for(int x=1;x<=h;x++)
                for(int y=1;y<=w;y++)
                {
                    for(int t=i;t<j;t++)
                        f[i][j][x][y]=min(f[i][j][x][y],f[i][t][x][y]+f[t+1][j][x][y]);
                    if(f[i][j][x][y]<inf) maxx=max(f[i][j][x][y],maxx),v[++tot]=make_pair(x,y);
                }
            spfa(i,j);
        }
    for(int i=1;i<=h;i++)
        for(int j=1;j<=w;j++) ans=min(ans,f[1][n][i][j]);
    if(ans==inf) puts("-1");
    else printf("%d\n",ans);
    return 0;
}
AIR780E二次开发点灯(LuatOS) Air780E的LuatOS点灯教程,二次开发教程,可用于所有ec618平台,无需SDK 阅读详情

相关推荐

SAP ABAP实战:用BAPI_PO_CREATE1创建采购订单时,如何巧妙处理PBXX和PB00条件类型?

本文深入探讨了在SAP ABAP开发中使用BAPI_PO_CREATE1创建采购订单时,如何有效处理PBXX和PB00条件类型的难题。通过分析外协加工订单的特殊需求,提供了从问题定位到解决方案的全流程方法,包括数据流向追踪、字段控制策略和增强实现方案,帮助开发者解决条件类型自动生成的业务痛点。

weixin_30614109的博客 824

[APIO2013]机器人(DP+SPFA最短路)

shortest path

255

优化求解器性能:当分支切割算法中的gap停滞不前时如何应对

本文深入探讨了当分支切割算法求解复杂整数规划问题时,gap停滞不前的根本原因与应对策略。文章指出gap停滞源于上界(找不到更优整数解)或下界(证明过程缓慢)提升受阻,并提供了从模型改写、自定义割平面、调整搜索策略到参数调优等一系列实战方法,帮助优化工程师有效打破求解僵局,推动gap下降。

weixin_29294597的博客 381

P3640 [APIO2013]出题人 题解

一道神仙图论题,很考验各位对最短路以及染色问题的理解。 首先说明 1 点,实质上神秘问题就是经典的染色问题。 这里首先简要分析一下给出的几个代码的特色: FloydWarshall:稳定的 O(V3)O(V^3)O(V3) 运行。下称 Floyd。 OptimizedBellmanFord:加了优化的 Bellman-Ford,但是只要在每一轮松弛的时候有一个点的 disdisdis 被改变了就会被彻底卡成 O(V2E)O(V^2E)O(V2E),于是负环可以排上用场。下称 Bellman-Ford/B

Plozia 的小窝 430

别再只盯着照片了!手把手教你用Python提取大疆照片里的GPS、姿态和RTK数据

本文详细介绍了如何使用Python提取大疆照片中的GPS、姿态和RTK数据,帮助用户解锁无人机拍摄照片中的隐藏元数据。通过实战代码示例,展示了如何解析EXIF格式的定位、姿态和RTK状态信息,并实现批量处理与数据分析,适用于测绘、农业巡检等专业领域。

weixin_30790841的博客 155

Paraview:Python Calculator Filter

python calculator过滤器 from paraview.simple import * connection = servermanager.Connect('localhost',11111) er = servermanager.sources.EnSightreader(CaseFileName='/.../data.case') er.PointArrays = ['x_velocity','1','y_velocity','1','z_velocity','1','cp','1']

haimianjie2012的专栏 3495

[APIO2013]机器人

所以说spfa能过真的正常吗?

StaroForgin的博客 238

国产麒麟V10系统命令大全,100个实用命令助你玩转系统!

国产麒麟V10系统命令大全,100个实用命令助你玩转系统!

网络技术联盟站 1910

bzoj 3205: [Apio2013]机器人 斯坦纳树

这道题目应该是比较明显的斯坦纳树吧。        令f[l][r][x][y]表示将编号l~r的机器人合并到(x,y)的最小代价,那么就有转移:       1. f[l][r][x][y]=min{f[l][k][x][y]+f[k+1][r][x][y]}       2. f[l][r][x1][y1]=min{f[l][r][x][y]+1},满足将(x,y)往某一个方向推之后会到

lych的博客 2224

108、AWB 时间滤波器:帧间白平衡平滑,防止色彩跳变与过冲

摘要: 文章探讨了AWB(自动白平衡)时间滤波器的设计与优化,以解决帧间白平衡跳变和过冲问题。通过自适应状态机(STABLE/TRANSITION/JUMP)动态调整平滑系数alpha,结合帧率归一化和过冲保护(方向检测+限幅),实现场景切换快速响应与静态稳定性的平衡。作者分享了工程经验:避免固定阈值、联动AE/AF、真实场景验证,并推荐简化卡尔曼滤波替代IIR。最终方案在旗舰机前置摄像头中成功消除“闪白”现象,强调参数需动态适应光照与色温变化。

sundong_81的博客 64

【ZYNQ】OV5640 图像采集与显示

OV5640 是豪威(OmniVision)半导体公司推出的高性能的 CMOS 数字图像传感器,支持最高 500 万像素图像采集,支持 RAW RGB、RGB565、YCbCr422 等图像格式输出,可应用于手机、平板等电子设备。本文主要介绍如何使用 Zynq 驱动 OV5640 摄像头进行图像采集,并通过 HDMI 实时显示。

洋洋Young的博客 1433

3205: [Apio2013]机器人

3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MB Submit: 525  Solved: 131 [Submit][Status][Discuss] Description VRI(Voltron机器人学会)的工程师建造了 n个机器人。任意两个兼容的机器人站在同一个格子时可以合并为一个复合机器人。我们把机器人用

CRZbulabula的博客 9353

Qt界面美化-飞扬青云自绘控件插件的使用-避免采坑

1、先上一个集成到QtCreater中的效果图: 2、飞扬青云自绘控件插件下载地址:https://gitcode.net/mirrors/feiyangqingyun/qucsdk?utm_source=csdn_github_accelerator 3、集成插件到QtCreater中的方法: (1)、查看自己使用的QtCreater的版本信息,我的:Qt 5.15.2 MSVC2019 64位 (2)插件下载下来后工程预览: 我选择msvc版本的SDK,打开找到匹配的SDK:...

小米的修行之路 2793

[APIO 2013] 机器人(斯坦纳树) | 错题本

文章目录题目分析代码 题目 [APIO 2013] 机器人 分析 先记搜出每个格子往上下左右推一下能滑到哪里。然后类似于斯坦纳树,定义 dp[l][r][x][y]dp[l][r][x][y]dp[l][r][x][y] 表示把 l∼rl \sim rl∼r 的所有机器人搞到 (x,y)(x, y)(x,y) 合并的最小代价,区间 DP 外加四联通的转移,一种转移情况是 dp[l][m][x][y]+dp[m+1][r][x][y]dp[l][m][x][y] + dp[m + 1][r][x][y]dp[

ixRic 290

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【BZOJ】【3205】【APIO2013】机器人robot

斯坦纳树   好神啊……Orzzyf &&PoPoQQQ   为啥跟斯坦纳树扯上关系了?我想是因为每个点(robot)都沿着树边汇到根的时候就全部合起来了吧= =这个好像和裸的斯坦纳树不太一样,那个是无向最小生成树,这个是有向图……   引用题解: 令f[l][r][i][j]表示在点(i,j)将编号在[l,r]区间内的机器人全部合并的最小推动次数 则有动规方...

weixin_30498807的博客 1560

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

BZOJ 3205 [Apio2013]机器人 斯坦纳树

题目大意:

YihAN_Z 1505

[Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)

3205: [Apio2013]机器人 Time Limit:15 SecMemory Limit:128 MBSubmit:977Solved:230[Submit][Status][Discuss] Description VRI(Voltron机器人学会)的工程师建造了 n个机器人。任意两个兼容的机器人站在同一个格子时可以合并为一个复合机器人...

weixin_30580341的博客 128

P3638 [APIO2013]机器人

题目链接 题目描述 VRI(Voltron 机器人学会)的工程师建造了 nnn 个机器人。任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人。 我们把机器人用 111 至 nnn 编号(n≤9n ≤ 9n≤9)。如果两个机器人的编号是连续的,那 么它们是兼容的,可以合并成一个复合机器人。最初这 nnn 个机器人各自都只有唯 一的编号。而一个由两个或以上的机器人合并构成的复合机器人拥有两个编号, 分别是构成它的所有机器人中最小和最大的编号。 例如,222 号机器人只可以与 111 号或 333 号

sky123博客 469

【题解】APIO2013机器人

  其实这题前前后后的思考时间加起来应该有两天之久了,dp状态,转移方式等等都还是比较好想,然而左看右看觉得spfa复杂度未免太爆炸……然后选择看了一篇题解,发现在多重优化之下,其实是可以过的……   首先建立状态,这个应该比较明显:\(f[l][r][x][y]\) 代表合并完区间 \(l\) ~\(r\) 之后,机器人停在 \(x,y\) 处所需要的最少移动次数。转移状态即为:   \(f...

weixin_30548917的博客 151

[APIO2013]机器人(斯坦纳树)

题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人。任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人。 我们把机器人用 1 至 n 编号(n ≤ 9)。如果两个机器人的编号是连续的,那 么它们是兼容的,可以合并成一个复合机器人。最初这 n 个机器人各自都只有唯 一的编号。而一个由两个或以上的机器人合并构成的复合机器人拥有两个编号, 分别是构成它的所有机器人...

weixin_34062329的博客 196

【bzoj3205】[Apio2013]机器人 斯坦纳树

f[l][r][i][j]表示把l到r的机器人合并,停在(i,j)点的最小步数 f[l][r][i][j]=min{f[l][k][i][j]+f[k+1][r][i][j]} f[l][r][i][j]=min{f[l][r][i'][j']+1} 记忆化搜索一下每个点从每个方向出发会走到哪里 注意,题目里可能出现环,要特判 spfa要加上一个优化才能通过 先把初始队列中的点按距离排

Oxer的专栏 1245

BZOJ3205: [Apio2013]机器人

卡常卡了好久qwq可以先用记忆化搜索搜出每个位置往四个方向走会走到哪,注意判走到已经走过的地方避免死循环 f[l][r][i][j]表示在(i,j)合成机器人l~r的最小花费 有 f[l][r][i][j]=min f[l][r][di][dj]+1 (di,dj)->(i,j) f[l][r][i][j]=min(f[l][k][i][j]+f[k+1][j][i][j]) 对于第二个转

L_0_Forever_LF的专栏 711

BZOJ 3205 Apio2013 机器人 斯坦纳树

题目大意:给定一张地图,一些地方有障碍物,有k 令f[l][r][i][j]表示在点(i,j)将编号在[l,r]区间内的机器人全部合并的最小推动次数 则有动规方程组: f[l][r][i][j]=min{f[l][r][_i][_j]+1} ( (_i,_j)->(i,j) ) f[l][r][i][j]=min(f[l][temp][i][j]+f[temp+1][r][i][j]) (

世界 3783
上一篇: 【JLOI2015 DAY2】通道连接
下一篇: 【Usaco Mar08 Gold】土地购买
StrideTG
博客等级 码龄9年 4粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值