AtCoder AGC004Eサルベージロボット(DP)

トピックリンク

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

問題の解決策

この質問の難しさは、一般的なアイデアを考えることが、どのように右のコードを書くことではありません。
まず、ロボットの動きを任せることはできないので、輸出および国境一緒に移動します。
次に、設定\(DP [L] [R ] [U] [D]が\) まで移動四方に出口を表す\(L、R、U、 Dの\) グリッド、いくつかのロボットを捕捉最大エネルギー。
下方例を転送:正当な条件をダウン遷移のため\(X_0 + D <NU \) \(X_0、Y_0 \)始点座標として)、出口の位置であるため、\(X_0 + D + 1 \ ) グリッド内の点は、正当に矩形リングの上下の境界を満たすようにしながら、より低い最もグリッドの境界位置する(NU \)\
上下法的均等物は正当ではないことに注意してください、このような状況は、開始点からです非常に遠く離れた下側の境界に近い国境から、そこにケースを完成させることができるされていますが、最初に以下の仕上げに乗る前に発生することがあります。
MLEは、圧延やオープン配列を防ぐことができますshort

時間複雑\(O(N ^ 4)\)

コード

#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;
}

おすすめ

転載: www.cnblogs.com/suncongbo/p/11564069.html