【AtCoder】(AtCoder Grand Contest 004)E - Salvage Robots

本文探讨了一个在有限网格中,通过合理规划使多个机器人从特定出口安全撤离的问题。利用动态规划思想,设计并实现了一种高效算法,该算法能够在不超过100x100的网格上找到最大数量的机器人撤离方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门:http://agc004.contest.atcoder.jp/tasks/agc004_e

大概翻译:
在一个H*W 的网格中有若干个机器人和一个出口,其余是空地。每次你可以让所有机器人往某个方向移动一步。当机器人移动到出口时候会被取出,当机器人移出网格时会爆炸。求你最多取出多少机器人。
H,W<=100

首先可以看出来取走一个机器人的代价是舍弃反方向的一些行列,所以可以发现能取走的机器人区域总体而言还是挺“方”的。
总而言之,做法就是枚举一个状态,f[i][j][k][p]表示拿走了的机器人的坐标(不一定要对应到实在的机器人,即可以对应取走空地)
然后枚举向上下左右拓展一行(列)分别能拿走多长的区间
tips:在纸上认真算好转移各种边界之类的

以上应该很好想到,所以这题的瓶颈不在于此,而是那个空间的问题……

同学:状态数最多50^4
我:那直接映射一个下标做
———–(各种迷+训练打乱了写题计划)———–
我:这东西写起来真恶心
同学:……(沉默)
同学:其实100^4个short不会炸空间……
我:(O__O “)…

#include<stdio.h>
#include<iostream>
#include<algorithm>
#define N 105
using namespace std;

short line[N][N],list[N][N],ans[N][N][N][N],n,m,op,sx,sy;
char s[N][N];

int main()
{
    cin>>n>>m;
    for (short i=1;i<=n;i++) scanf("%s",s[i]+1);
    for (short i=1;i<=n;i++) for (short j=1;j<=m;j++)
    {
        line[i][j]=line[i][j-1]+(s[i][j]=='o');
        list[i][j]=list[i-1][j]+(s[i][j]=='o');
        if (s[i][j]=='E') sx=i,sy=j;
    }
    for (short i=sx;i;i--) for (short j=sy;j;j--) 
        for (short k=sx;k<=n;k++) for (short p=sy;p<=m;p++)
    {
        if (1<i && k+1<sx+i) op=max(op,ans[i-1][j][k][p]=max((int)ans[i-1][j][k][p],ans[i][j][k][p]+line[i-1][min((int)p,m-sy+j)]-line[i-1][max(j-1,p-sy)]));
        if (k<n && sx+k<n+i) op=max(op,ans[i][j][k+1][p]=max((int)ans[i][j][k+1][p],ans[i][j][k][p]+line[k+1][min((int)p,m-sy+j)]-line[k+1][max(j-1,p-sy)]));
        if (1<j && p+1<sy+j) op=max(op,ans[i][j-1][k][p]=max((int)ans[i][j-1][k][p],ans[i][j][k][p]+list[min((int)k,n-sx+i)][j-1]-list[max(i-1,k-sx)][j-1]));
        if (p<m && sy+p<m+j) op=max(op,ans[i][j][k][p+1]=max((int)ans[i][j][k][p+1],ans[i][j][k][p]+list[min((int)k,n-sx+i)][p+1]-list[max(i-1,k-sx)][p+1]));
    }
    cout<<op;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值