zoukankan      html  css  js  c++  java
  • 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
    ",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();
    }
    
    
  • 相关阅读:
    软件工程第三次作业
    软件工程第一次作业
    软件工程第0次作业
    第2次作业
    第1次作业
    第0次作业
    软件工程第四次作业 石墨文档IOS
    软件工程第三次作业
    软件工程第一次作业
    第零次作业
  • 原文地址:https://www.cnblogs.com/lcxer/p/10741797.html
Copyright © 2011-2022 走看看