AtCoder AGC004E Salvage Robots (DP)

Topic Link

https://atcoder.jp/contests/agc004/tasks/agc004_e

answer

The difficulty of this question is not to think of the general idea, but how to write the code right. .
First, we can not let the robot move, so export and border move together.
Then set \ (dp [l] [r ] [u] [d] \) represents the outlet to the four directions moving up \ (l, r, u, d \) grid, the maximum energy trapping several robots.
Transfer downward Example: legitimate conditions for transition down \ (x_0 + D <NU \) ( \ (x_0, y_0 \) as the starting point coordinate), because the position of the outlet is \ (x_0 + d + 1 \ ) while the point within the grid to meet the upper and lower boundaries of the rectangular ring into legitimate, the boundary position of the lower most grid to \ (NU \) .
Note that the upward and downward legal equivalents are not legitimate, such a situation is the starting point from very far away from the border close to the lower boundary, there is the case can be completed but before you get on the finish of the first following may occur.
MLE can prevent rolling or open array short.

Time complexity \ (O (n-^. 4) \) .

Code

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cassert>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 100;
short dp[N+3][N+3][N+3][N+3];
int s[N+3][N+3];
char a[N+3][N+3];
int n,m,sx,sy;

int getsum(int lx,int rx,int ly,int ry) {return s[rx][ry]-s[lx-1][ry]-s[rx][ly-1]+s[lx-1][ly-1];}

int updmax(short &x,short y) {x = x>y?x:y;}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%s",a[i]+1);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            s[i][j] = (a[i][j]=='o'?1:0)+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
            if(a[i][j]=='E') {sx = i,sy = j;}
        }
    }
    memset(dp,213,sizeof(dp));
    dp[0][0][0][0] = 0; short ans = 0;
    for(int l=0; sy-l>0; l++)
    {
        for(int r=0; sy+r<=m; r++)
        {
            for(int u=0; sx-u>0; u++)
            {
                for(int d=0; sx+d<=n; d++)
                {
                    updmax(ans,dp[l][r][u][d]);
                    int ly = max(1+r,sy-l),ry = min(m-l,sy+r),lx = max(1+d,sx-u),rx = min(n-u,sx+d);
//                  printf("l%d r%d u%d d%d x[%d,%d] y[%d,%d]\n",l,r,u,d,lx,rx,ly,ry);
                    if(sx+d<n-u)
                    {
                        updmax(dp[l][r][u][d+1],dp[l][r][u][d]+getsum(sx+d+1,sx+d+1,ly,ry));
                    }
                    if(sx-u>1+d)
                    {
                        updmax(dp[l][r][u+1][d],dp[l][r][u][d]+getsum(sx-u-1,sx-u-1,ly,ry));
                    }
                    if(sy+r<m-l)
                    {
                        updmax(dp[l][r+1][u][d],dp[l][r][u][d]+getsum(lx,rx,sy+r+1,sy+r+1));
                    }
                    if(sy-l>1+r)
                    {
                        updmax(dp[l+1][r][u][d],dp[l][r][u][d]+getsum(lx,rx,sy-l-1,sy-l-1));
                    }
                }
            }
        }
    }
    printf("%d\n",(int)ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/11564069.html