[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,r][l,r]区间内的所有机器人的最小花费

toi,j,k:to_{i,j,k}:toi,j,k:(i,j)(i,j)(i,j)kkk方向推机器人最终停止的位置,用dfs记忆化搜索模拟即可

dpl,r,i,j=min⁡{dpl,k,i,j+dpk+1,r,i,j∣l≤i<r}dp_{l,r,i,j}=\min\{dp_{l,k,i,j}+dp_{k+1,r,i,j}\big| l\le i<r\}dpl,r,i,j=min{dpl,k,i,j+dpk+1,r,i,jli<r}

dpl,r,i,j+1→toi,j,kdp_{l,r,i,j}+1\rightarrow to_{i,j,k}dpl,r,i,j+1toi,j,k 该转移就是一层在(i,j)(i,j)(i,j)位置上的最短路,用类bfsspfa跑即可

code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f
#define LEN 500000
struct node {int x, y;node(){}node( int X, int Y ) {x = X, y = Y;}
}robot[10], to[505][505][4], s[500005], t[500005];
int n, col, row, cnt, top;
char room[505][505];
int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, -1, 0, 1 };
int f[10][10][505][505];
int id[505][505][4];
bool vis[505][505];
int w[1000005], sum[1000005];node dfs( int x, int y, int k ) {if( id[x][y][k] == cnt ) return node( 0, -1 );id[x][y][k] = cnt;if( to[x][y][k].y ) return to[x][y][k];int dir = k;if( room[x][y] == 'C' ) dir = ( dir + 1 ) % 4;if( room[x][y] == 'A' ) dir = ( dir + 3 ) % 4;int tx = x + dx[dir], ty = y + dy[dir];if( tx < 1 || tx > row || ty < 1 || ty > col || room[tx][ty] == 'x' )return to[x][y][k] = node( x, y );elsereturn to[x][y][k] = dfs( tx, ty, dir );
}void spfa( int l, int r ) {memset( sum, 0, sizeof( sum ) );memset( vis, 0, sizeof( vis ) );int minn = inf, maxx = -inf;for( int i = 1;i <= top;i ++ ) {sum[w[i]] ++;minn = min( minn, w[i] );maxx = max( maxx, w[i] );vis[s[i].x][s[i].y] = 1;}//类后缀数组方法对队列中当前层位置进行手动排序编号 for( int i = minn + 1;i <= maxx;i ++ ) sum[i] += sum[i - 1];for( int i = top;i;i -- )t[sum[w[i]] --] = s[i];for( int i = 1;i <= top;i ++ )s[i] = t[top - i + 1];int head = 0, tail = 0, now; node u, v;//%LEN:手动进行空间回收利用 while( top || head != tail ) {now = head % LEN + 1;if( head == tail || ( top && f[l][r][s[top].x][s[top].y] < f[l][r][t[now].x][t[now].y] ) )u = s[top], top --;elsehead = now, u = t[head];vis[u.x][u.y] = 0;for( int i = 0;i < 4;i ++ ) {v = to[u.x][u.y][i]; if( v.x && f[l][r][v.x][v.y] > f[l][r][u.x][u.y] + 1 ) {f[l][r][v.x][v.y] = f[l][r][u.x][u.y] + 1;if( ! vis[v.x][v.y] ) {vis[v.x][v.y] = 1;tail = tail % LEN + 1;t[tail] = v;}}}}
}int main() {memset( f, 0x3f, sizeof( f ) );scanf( "%d %d %d", &n, &col, &row );for( int i = 1;i <= row;i ++ ) {scanf( "%s", room[i] + 1 );for( int j = 1;j <= col;j ++ )if( room[i][j] < '0' || room[i][j] > '9' )continue;else {int k = room[i][j] - '0';robot[k] = node( i, j );f[k][k][i][j] = 0;}}//to(i,j,k):(i,j)位置按k方向推机器人最终停止的位置 for( int i = 1;i <= row;i ++ )for( int j = 1;j <= col;j ++ )if( room[i][j] == 'x' )continue;elsefor( int k = 0;k < 4;k ++ )cnt ++, to[i][j][k] = dfs( i, j, k );for( int i = 1;i <= n;i ++ )s[top = 1] = robot[i], w[1] = 0, spfa( i, i );//f(l,r,i,j,):在(i,j)位置上合并[l,r]编号内的机器人的最小花费 for( int len = 1;len <= n;len ++ )//区间DP 由小到大 for( int l = 1;l <= n;l ++ ) {int r = l + len;if( r > n ) break;for( int i = 1;i <= row;i ++ )for( int j = 1;j <= col;j ++ )for( int k = l;k < r;k ++ )f[l][r][i][j] = min( f[l][r][i][j], f[l][k][i][j] + f[k + 1][r][i][j] );top = 0;for( int i = 1;i <= row;i ++ )for( int j = 1;j <= col;j ++ )if( f[l][r][i][j] < inf ) //状态本身要存在才能进行下一层转移 s[++ top] = node( i, j ), w[top] = f[l][r][i][j];spfa( l, r );}int ans = inf;for( int i = 1;i <= row;i ++ )for( int j = 1;j <= col;j ++ )ans = min( ans, f[1][n][i][j] );printf( "%d\n", ans < inf ? ans : -1 );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IdentityServer4实战 - 与API单项目整合

一.前言我们在实际使用 IdentityServer4 的时候&#xff0c;可能会在使用 IdentityServer4 项目添加一些API&#xff0c;比如 找回密码、用户注册、修改用户资料等&#xff0c;这些API与IdentityServer4怎么共存在一个项目呢&#xff1f;二.整合1.首先在 Startup.cs 中添加 Ide…

P2305 [NOI2014] 购票(点分治、斜率优化)

解析 第一道完全自己做出来的黑题awa &#xff08;如果不算那道感觉完全是恶评的石油的话&#xff09; 然而连写带调整了3.5h… 容易想到链的做法 设ancxanc_xancx​表示x的祖先,disxdis_xdisx​表示x到1的距离 则有&#xff1a; dpvmin⁡disv−lv<disu,u∈ancv(dpupv(dis…

HDU1394(权值线段树)

HDU1394(权值线段树) 题意&#xff1a; 给定一个0到n-1的数字组成的序列&#xff0c;可以将序列进行左移任意次&#xff0c;求所能组成序列的逆序对的最小值 题解&#xff1a; 利用权值线段树&#xff0c;我们先求出当前序列所能组成的逆序对&#xff0c; 然后依次左移动 当…

P8339-[AHOI2022]钥匙【虚树,扫描线】

正题 题目连接:https://www.luogu.com.cn/problem/P8339 题目大意 给出nnn个点的一棵树&#xff0c;每个点有钥匙或者宝箱&#xff0c;有不同的颜色。 mmm次询问&#xff0c;从xxx走到yyy&#xff0c;走到钥匙时会拾取钥匙&#xff0c;走到宝箱时如果有同色的钥匙那么就会消耗…

[HDU 6157]The Karting(DP)

[HDU 6157]The Karting description solution 先用前缀和求出di:1→id_i:1\rightarrow idi​:1→i 的距离 前缀和满足&#xff1a;若在iii点进行方向改变&#xff0c;则iii产生的贡献是一定的&#xff0c;可以先累计贡献 也就是说真正的路径怎么走&#xff0c;我们是不关心…

.NET 开源简史

现在在微软开发开源软件是很一件正常的事情——但在 2007 年&#xff0c;当时我刚加入微软&#xff0c;那时候可不是这么一回事。微软花了好几年时间才找到正确的方向&#xff0c;让微软这艘大船顺着开源之风向前航行。现在回头远望过去那些曾经面临的挑战&#xff0c;我们一笑…

P2617 Dynamic Rankings(整体二分)

P2617 Dynamic Rankings 题意: 待修改的区间最值问题 题解&#xff1a; 整体二分天然带有修改性 整体二分做不带修改的区间最值—>看这里 现在待修改&#xff0c;我们可以将第l位修改为x&#xff0c;因为我们是用树状数组来维护的&#xff0c;所以把这个过程拆分成将第l个…

模板:虚树

所谓虚树&#xff0c;就是虚了的树 &#xff08;逃&#xff09; 前言 在有些时候&#xff0c;我们只关心树上的某些特殊点&#xff0c;问题中的整体规模较大&#xff0c;但是这些特殊点往往比较稀疏&#xff0c;这个时候就可以使用虚树&#xff0c;只保留树上的关键点&#x…

P8340-[AHOI2022]山河重整【dp,倍增】

正题 题目链接:https://www.luogu.com.cn/problem/P8340 题目大意 给出一个nnn和模数PPP。求有多少个在1∼n1\sim n1∼n中选择若干个数的集合SSS&#xff0c;满足1∼n1\sim n1∼n中的每个数都可以表示成SSS的某个子集的和。 1≤n≤5105,2≤P≤1.11091\leq n\leq 5\times 10^5…

[LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

[LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心&#xff08;满足最重的儿子最轻&#xff0c;每个儿子siz≤n2\le\frac{n}{2}≤2n​&#xff09; 显然原树的重心答案为0 对于点iii&am…

由优劣语言之争引起的思考

由优劣语言之争引起的思考#欲使其灭亡&#xff0c;必使其疯狂昨天上午由阿里云中间件公众号和架构师小秘圈公众号发布的一篇文章《天天敲代码会使人变聪明么》在.net开发者中掀起了一阵巨浪&#xff0c;文章中提到的语言的先进与落后之争让基于.net开发者们义愤填膺&#xff0c…

P1527 [国家集训队]矩阵乘法

P1527 [国家集训队]矩阵乘法 题意&#xff1a; 给你一个 nn 的矩阵&#xff0c;每次询问一个子矩形的第 k 小数。 题解&#xff1a; 整体二分稍微加强化 模板题是一个序列&#xff0c;现在升级成一个矩阵求&#xff0c;做法和原理都是一样的 使用整体二分解决的题目&#x…

[LOJ #521]「LibreOJ β Round #3」绯色 IOI(抵达)(结论)

#521. 「LibreOJ β Round #3」绯色 IOI&#xff08;抵达&#xff09; description solution 因为点的庇护所不能为自身&#xff0c;题目背景在树上&#xff0c;有结论一定是两个相邻点互为庇护所 所以树一定要能两两完美匹配才有解 判断完有解后就是构造解了&#xff0c;…

UOJ#310-[UNR #2]黎明前的巧克力【FWT】

1# 正题 题目链接:https://uoj.ac/problem/310 题目大意 给出一个长度为nnn的序列&#xff0c;求有多少种方案找出两个集合S,TS,TS,T使得这两个集合的异或和相等。 1≤n≤1061\leq n\leq 10^61≤n≤106 解题思路 可以转换为找到一个异或和为000的集合SSS&#xff0c;产生2∣S…

ybtoj洛谷P4426:毒瘤(虚树,环套树,暴力)

传送门 解析 顾名思义&#xff0c;十分毒瘤 但有一说一&#xff0c;相对来说这题没有之前做的那两个黑题那么&#xff08;重读&#xff09;恶心 而且本题如果放在考场上&#xff0c;暴力枚举非树边的状态dp就可以拿到70分的好成绩&#xff08;改一改能改到75&#xff09; 现…

微软是如何使用 C# 重写 C# 编译器并将其开源的

Roslyn 是 C# 和 Visual Basic.NET 开源编译器的代号。这篇文章将介绍它是如何从微软过去的十年至暗时刻走出来&#xff0c;成为开源跨平台的 C# 和 VB 公共语言引擎。我于 2005 年加入微软&#xff0c;也就是在.NET 2.0 发布之前&#xff0c;当时微软内部已经开始在讨论 Rosly…

P3332 [ZJOI2013]K大数查询(整体二分做法)

P3332 [ZJOI2013]K大数查询 题意: 题解&#xff1a; 利用整体二分来做&#xff0c;这个题和P3834 【模板】可持久化线段树 2的区别在于本题的修改是区间修改&#xff0c;所以将里面的树状数组改成线段树就行&#xff0c;区间修改区间查询 但是不知道为什么我调了一阵子也不对…

[APIO2020]交换城市(交互+kruskal重构树)

[APIO2020]交换城市 description solution 如果u,vu,vu,v存在于一条链上&#xff08;只有两个点度数为111其余点度数为222&#xff09;则无解&#xff0c;否则必有解 如图&#xff0c;不管是哪个点度数>2>2>2&#xff0c;都可以有解 以蓝色为例&#xff0c;第二个…

P3320:寻宝游戏(生成树)

解析 大结论题… 实在是不知道这题和虚树有半毛钱关系吗… 引理 给出一个按照dfs排列的点集S{a1,a2…ak} 它们的极小联通子树的边权和的二倍等于∑dis(a1,a2)dis(a2,a3)...dis(ak−1,ak)dis(ak,a1)\sum dis(a_1,a_2)dis(a_2,a_3)...dis(a_k-1,a_k)dis(a_k,a_1)∑dis(a1​,a2​…

P5333-[JSOI2019]神经网络【dp,容斥】

正题 题目链接:https://www.luogu.com.cn/problem/P5333 题目大意 给出nnn棵树&#xff0c;第iii棵树有kik_iki​个点&#xff0c;每棵树上的每个点和其它树上的所有点都有连边。 求这棵树有多少条哈密顿回路。 答案对998244353998244353998244353取模。 ∑i1nki≤5000\sum…