G - AtCoder Tour

G - AtCoder Tour

Problem Statement

AtCoder Land is represented by a grid with H rows and W columns. Let (i,j) denote the cell at the i-th row and j-th column.

Takahashi starts at cell (Si,Sj) and repeats the following action K times:

  • He either stays in the current cell or moves to an adjacent cell. After this action, if he is in cell (i,j), he gains a fun value of Ai,j.

Find the maximum total fun value he can gain.

Here, a cell (x,y) is considered adjacent to cell (x,y) if and only if |xx|+|yy|=1.

Constraints

  • 1H,W50
  • 1K109
  • 1SiH
  • 1SjW
  • 1Ai,j109
  • All input values are integers.

Input

The input is given from Standard Input in the following format:

H W K
Si Sj
A1,1 A1,2 A1,W
A2,1 A2,2 A2,W

AH,1 AH,2 AH,W

Output

Print the answer.


Sample Input 1

2 3 3
1 2
2 1 2
3 4 5

Sample Output 1

14

Takahashi can gain a total fun value of 14 by acting as follows:

  • Initially, he is at (1,2).
  • He moves to cell (2,2). Then, he gains a fun value of A2,2=4.
  • He moves to cell (2,3). Then, he gains a fun value of A2,3=5.
  • He stays in cell (2,3). Then, he gains a fun value of A2,3=5.

He cannot gain a total fun value greater than 14, so print 14.


Sample Input 2

2 2 1000000000
2 1
100 100
100 99

Sample Output 2

100000000000

 

解题思路

  对于任意一条以 (sx,sy) 为起点的路径,假设 (tx,ty) 是路径中经过的权值最大的格子,那么在路径中第一次经过 (tx,ty) 之后的格子是完全没必要访问的,因为 (tx,ty) 处的权值大于或等于之后要访问的格子,因此停留在 (tx,ty) 处所获得的收益更大。同时在 (sx,sy)(tx,ty) 的过程中,除了 (tx,ty) 外,每个格子最多会被访问一次,否则路径中会存在一个环,容易知道把环去掉以更多的停留在 (tx,ty) 所能获得的收益更大。因此在最优解中,最后必然是停留在某个格子上,且从 (sx,sy) 到该格子路径上每个格子最多被访问一次。

  为此,我们可以按最后停留的格子对所有情况进行分类。当确定最后停留的格子是 (i,j) 后,如何确定 (sx,sy)(i,j) 的路径?一个错误的贪心思路是走一条长度为 |sxi|+|syj| 的权值最大的路径,然后剩下的步数都停留在 (i,j)。可以参考下面的样例发现错误:

2 4 5
1 1
1 1 1 100
99 99 99 99

  错误的贪心思路结果为 1+1+100+100+100,而最优解是 99+99+99+99+100

  显然我们可以多走几格,又因为从 (sx,sy)(i,j) 的过程中每个格子最多被访问一次,因此最多会走 nm 个格子。定义 f(u,i,j) 表示以 (sx,sy) 为起点,无重复经过 u 个格子到达 (i,j) 的所有方案中权值和的最大值。状态转移方程就是 f(u,i,j)=max|ix|+|jy|=1{f(u1,x,y)+wi,j}

  最后答案就是 maxu,i,j{f(u,i,j)+(ku)wi,j}

  AC 代码如下,时间复杂度为 O(n2m2)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 55;

int g[N][N];
LL f[N * N][N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int main() {
    int n, m, k, x, y;
    scanf("%d %d %d %d %d", &n, &m, &k, &x, &y);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &g[i][j]);
        }
    }
    memset(f, -0x3f, sizeof(f));
    f[0][x][y] = 0;
    for (int u = 1; u < n * m && u <= k; u++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                for (int k = 0; k < 4; k++) {
                    int x = i + dx[k], y = j + dy[k];
                    if (i <= 0 || i > n || j <= 0 || j > m) continue;
                    f[u][i][j] = max(f[u][i][j], f[u - 1][x][y] + g[i][j]);
                }
            }
        }
    }
    LL ret = 0;
    for (int u = 0; u < n * m && u <= k; u++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                ret = max(ret, f[u][i][j] + LL(k - u) * g[i][j]);
            }
        }
    }
    printf("%lld", ret);
    
    return 0;
}

 

参考资料

  Editorial - AtCoder Beginner Contest 358:https://atcoder.jp/contests/abc358/editorial/10226

posted @   onlyblues  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示