AT2045 Salvage Robots

传送门

这个题只要想到移动机器人和移动出口是等价的就好做了
考虑设\(f[i][j][k][t]\)为最远向左移动\(i\),向右移动\(j\),向上移动\(k\),向下移动\(t\),这个矩形内最多能救的机器人
转移就记录一个前缀和来辅助转移,这样复杂度就在能通过的范围内了
但是转移还是比较麻烦的,还需要考虑当前状态下哪些机器人是已经死了的
空间有点卡,可以选择开short也可以将第一维滚动
代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
void read(int &x){
    char ch;bool ok;
    for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
    for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
#define rg register
const int maxn=110;
#define max(a,b) ((a)>(b)?(a):(b))
short ans,f[maxn][maxn][maxn][maxn],l[maxn][maxn],r[maxn][maxn];
int n,m,x,y;char s[maxn];
void solve(){
    int le=y-1,rt=m-y,up=x-1,dw=n-x;
    for(rg int i=0;i<=le;i++)
        for(rg int j=0;j<=rt;j++)
            for(rg int k=0;k<=up;k++)
                for(rg int t=0;t<=dw;t++){
                    if(y-i-1>j){
                        int now1=max(x-k,t+1),now2=min(x+t,n-k);
                        f[i+1][j][k][t]=max(f[i+1][j][k][t],f[i][j][k][t]+r[now2][y-i-1]-r[now1-1][y-i-1]);
                    }
                    else f[i+1][j][k][t]=max(f[i+1][j][k][t],f[i][j][k][t]);
                    
                    if(y+j+1+i<=m){
                        int now1=max(x-k,t+1),now2=min(x+t,n-k);
                        f[i][j+1][k][t]=max(f[i][j+1][k][t],f[i][j][k][t]+r[now2][y+j+1]-r[now1-1][y+j+1]);
                    }
                    else f[i][j+1][k][t]=max(f[i][j+1][k][t],f[i][j][k][t]);
                    
                    if(x-k-1>t){
                        int now1=max(y-i,j+1),now2=min(y+j,m-i);
                        f[i][j][k+1][t]=max(f[i][j][k+1][t],f[i][j][k][t]+l[x-k-1][now2]-l[x-k-1][now1-1]);
                    }
                    else f[i][j][k+1][t]=max(f[i][j][k+1][t],f[i][j][k][t]);
                    
                    if(x+t+1+k<=n){
                        int now1=max(y-i,j+1),now2=min(y+j,m-i);
                        f[i][j][k][t+1]=max(f[i][j][k][t+1],f[i][j][k][t]+l[x+t+1][now2]-l[x+t+1][now1-1]);
                    }
                    else f[i][j][k][t+1]=max(f[i][j][k][t+1],f[i][j][k][t]);
                }
    printf("%d\n",f[le][rt][up][dw]);
}
int main(){
    read(n),read(m);
    for(rg int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(rg int j=1;j<=m;j++){
            if(s[j]=='E')x=i,y=j;
            else if(s[j]=='o')l[i][j]=r[i][j]=1;
        }
    }
    for(rg int i=1;i<=n;i++)
        for(rg int j=1;j<=m;j++)
            l[i][j]+=l[i][j-1];
    for(rg int i=1;i<=m;i++)
        for(rg int j=1;j<=n;j++)
            r[j][i]+=r[j-1][i];
    solve();
}
posted @ 2019-04-20 17:39 蒟蒻--lichenxi 阅读(...) 评论(...) 编辑 收藏