传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3205

思路:类似斯坦纳树的想法

但是因为这里的合并必须连号

所以子集枚举就变成了区间合并

说说做法好了

首先记搜搜出每个点向四个方向走一步会到哪里

注意:转向器可能导致机器人一直在里面转出不来,要特判掉

然后设f[l][r][x][y]表示当前合并的机器人是[l,r],合并点是(x,y)

两种转移:

枚举子区间,合并f[l][r][x][y]=min(f[l][mid][x][y],f[mid+1][r][x][y])

从另一个地方转移过来f[l][r][x][y]=min(f[l][r][xx][yy]) (xx,yy)走一步能到(x,y)

然后还不够

第二种转移的spfa要加一个杂技优化

观察这个图 发现所有边的边权都是1 如果是单源的话SPFA可以进化成广搜

现在是多源 因此我们可以这样做:

维护两个队列,将初始所有的点按照距离排序后从小到大加入队列1

每次拓展出的点加入队列2

每次取出点的时候,如果队列1队尾元素的距离小于队列2 就把队列1的队尾元素拿去松弛 否则就用队列2的

这样做之后除了排序之外复杂度是线性的

排序的log可以用计数排序省掉,但是直接sort也能过,无妨

然后这题就搞掉了。。。。。。

------以上内容来自popoqqq的博客

然后就卡过了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define id(x,y) id[x][y]
const int maxn=505,maxk=10,maxb=maxn*maxn,inf=1e9;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
using namespace std;
int n,h,w,next[maxb][4],pos[maxk],f[maxk][maxk][250005],cnt,ans,*dist,id[maxn][maxn],q1[maxb*10],q2[maxb*10];
bool bo[maxb],vis[maxb][4];char map[maxn][maxn];
//inline int id(int x,int y){return x*(h+1)+y;}
inline bool ok(int x,int y){return x>0&&x<=w&&y>0&&y<=h&&map[x][y]!='x';}
inline void decode(int s,int &x,int &y){x=(s-1)/h+1,y=(s-1)%h+1;}
inline bool cmp(int x,int y){return dist[x]<dist[y];}void dfs(int x,int y,int d){int s=id(x,y);if (vis[s][d]) return;vis[s][d]=1;next[s][d]=-1;int nx=x+dx[d],ny=y+dy[d];//printf("%d %d %d\n",x,y,d);if (!ok(nx,ny)) {next[id(x,y)][d]=id(x,y);return;}int newd=d;if (map[nx][ny]=='A') newd=(newd+3)%4;if (map[nx][ny]=='C') newd=(newd+1)%4;dfs(nx,ny,newd);next[s][d]=next[id(nx,ny)][newd];
}void init(){scanf("%d%d%d",&n,&h,&w);for (int i=1;i<=w;i++){scanf("%s",map[i]+1);for (int j=1;j<=h;j++){id(i,j)=++cnt;if (isdigit(map[i][j])) pos[map[i][j]-'0']=id(i,j);//   printf("%d ",id[i][j]);}}//for (int i=1;i<=n;i++) printf("%d\n",pos[i]);
}void bfs(int *d){int h1=0,t1=-1,h2=0,t2=-1;dist=d;for (int i=1;i<=cnt;i++) if (dist[i]!=inf) q2[++t2]=i;//printf("dist=%d\n",i);memset(bo,0,sizeof(bo));sort(q2,q2+1+t2,cmp);while (h1<=t1||h2<=t2){//puts("%p");int s,x,y;if (h1>t1) s=q2[h2++];else if (h2>t2) s=q1[h1++];else{if (dist[q1[h1]]<dist[q2[h2]]) s=q1[h1++];else s=q2[h2++];}decode(s,x,y);//printf("%d %d %d\n",s,x,y);bo[s]=1;for (int i=0;i<4;i++){int ns=next[s][i];if (ns!=-1&&dist[ns]>dist[s]+1){dist[ns]=dist[s]+1;bo[ns]=1,q1[++t1]=ns;}}while (h2<=t2&&bo[q2[h2]]) h2++;}
}void work(){for (int i=1;i<=w;i++)for (int j=1;j<=h;j++)if (map[i][j]!='x')for (int d=0;d<4;d++)dfs(i,j,d);//dfs(1,1,3);for (;;);
/*  for (int k=0;k<4;k++,puts("\n"))for (int i=1;i<=w;i++,puts(""))for (int j=1;j<=h;j++){//int x,y;decode(next[id(i,j)][k],x,y);printf("%d ",next[id(i,j)][k]);//        printf("(%d,%d) ",x,y);}*/for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)for (int k=1;k<=cnt;k++) f[i][j][k]=inf;for (int i=1;i<=n;i++)f[i][i][pos[i]]=0;for (int len=1;len<=n;len++)for (int l=1;l+len-1<=n;l++) {int r=l+len-1;for (int mid=l;mid<r;mid++)for (int p=1;p<=cnt;p++) f[l][r][p]=min(f[l][r][p],f[l][mid][p]+f[mid+1][r][p]);//printf("%d ",f[l][r][1]);//printf("%d %d\n\n\n\n",l,r);bfs(f[l][r]);}ans=inf;for (int i=1;i<=cnt;i++) ans=min(ans,f[1][n][i]);printf("%d\n",ans==inf?-1:ans);
}int main(){init(),work();return 0;
}
/*
4 10 5
1.........
AA...x4...
..A..x....
2....x....
..C.3.A...
*/

bzoj3205: [Apio2013]机器人相关推荐

  1. bzoj3205 [Apio2013]机器人

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3205 http://uoj.ac/problem/107 [题解] 我们发现这就是一棵斯坦纳 ...

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

    [APIO2013]机器人 description solution dpl,r,i,j:dp_{l,r,i,j}:dpl,r,i,j​: 在(i,j)(i,j)(i,j)位置合并编号为[l,r][l ...

  3. 3205: [Apio2013]机器人

    3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MB Submit: 525  Solved: 131 [Submit][Statu ...

  4. [APIO2013]机器人[搜索、斯坦纳树]

    题意 题目链接 分析 记 g(d,x,y) 表示从 (x,y) 出发,方向为 d 到达的点,这个可以通过记忆化搜索求出,注意如果转移成环(此时向这个方向走没有意义)要特判. 记 f(l,r,x,y) ...

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

    题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人.任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人. 我们把机器人用 1 至 n 编号(n ≤ 9).如果两个机 ...

  6. 【BZOJ3205_洛谷3638】[APIO2013]机器人(动态规划)

    题目: 洛谷3638 分析: 卡了一天的神题--(OrzJumpmelon) 首先预处理出从点\(p\)向\(d\)方向出发最终能到达的点\(nxt[p][d]\).这个可以直接记忆化搜索解决.如果出 ...

  7. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  8. 【QBXT】学习笔记——Day3/4图论+dp

    继续上传一波笔记吧. Day3 1.16AM 今天讲图论,以习题为主. 开篇水题: 给一幅图,若删去一个点后变成一棵树,则这个点合法.问哪些点合法. 思路根据树的性质:这个点不是割点,m-这个点的度数 ...

  9. [总结]2019年9月 OI学习/刷题记录

    从现在开始记录一下每天的学习情况.主力LOJ? 2019/9/5 LibreOJ #2543. 「JXOI2018」排序问题 答案显然是\(\frac{(n+m)!}{Cnt_1!Cnt_2!\cdo ...

最新文章

  1. 【AI思辨】八年之痒!除了NLP和CV,人工智能就不能干点别的啥了?
  2. Leetcode | Binary Tree Maximum Path Sum
  3. **【POJ - 3122】 Pie(二分寻值)
  4. 在.Net中,如何创建一个后台执行的进程?
  5. datetime 比较_Python 字典中key命中取值的两种方法性能比较!
  6. 分布式配置中心之 —— nacos使用详解
  7. golang 关闭gc 并手动gc_Golang垃圾回收 屏障技术
  8. Bellman_Ford算法(求一个点到任意一点的最短距离)
  9. Flutter代码锦囊---淘口令复制弹窗
  10. git log控制输出宽度
  11. 实习成长之路——设计模式二:为什么项目都是基于接口而非实现编程?有必要为每个类都定义接口吗?
  12. thinkphp5基于php的校园微博系统--php-计算机毕业设计
  13. mysql 数据库清理 磁盘空间
  14. 2013-06-16 读书笔记 大前研一 《无国界的世界》
  15. chemdraw怎么画拐弯的箭头_怎么样绘制弧形箭头?
  16. php根据淘宝短链接获取商品ID
  17. macd的python代码同花顺_超牛MACD(代编写程序化交易模型)-同花顺公式 -程序化交易(CXH99.COM)...
  18. 修改远程桌面3389端口批处理
  19. 二. 应用加速(微服务架构设计的cdn访问加速)
  20. Python居然能破解传说中的摩斯密码?“有内鬼,终止交易”

热门文章

  1. unity音量++_Björk+ Unity:现场Mocap新闻发布会
  2. 百度无人驾驶出租车正式上路
  3. 互联网公司招聘--58集团--前端--2017年笔试题1
  4. Quartz是如何到期触发定时任务的
  5. matlab里meshgrid函数,matlab中meshgrid函数
  6. Python中的一些小知识
  7. 值得学的C++餐厅餐饮管理点菜系统!
  8. PPT排版 驼峰设计 PPT代做
  9. 2021-第五届世界智能大会-「津门杯」国际网络安全创新大赛-Web-hate_php
  10. Linux(Ubuntu)用户与用户组(入门必看)