本文同步发于洛谷博客,您也可以在题解页面访问。

因为题目输入格式,输出格式和数据范围没给全。所以我补充一下。

题目翻译

输入格式

第一行输入 TT 表示有 TT 组数据。每组数据中第一行两个整数 R,CR,C ,接下来输入一个 RRCC 列的网格 SS ,如果 Si,j<0S_{i,j} < 0 表示恐龙,否则表示药水。

输出格式

输出包含 TT 组数据,每组数据输出一个正整数,表示由单元格 1,11,1 到单元格 R,CR,C 的最小力量值。

数据范围与约定

1T51 \leq T \leq 5

2R,C5002 \leq R,C \leq 500

103Si,j103-10^3 \leq S_{i,j} \leq 10^3

S1,1=SR,C=0S_{1,1} = S_{R,C} = 0

下面回归正轨


解题思路

这道题是一道明显的 dp 题。

定义状态:

dpi,jdp_{i,j} 表示从第 ii 行第 jj 列走到第 RR 行第 CC 列所需最小体力值。

初始状态:

dpR,C=1dp_{R,C} = 1 ,因为 SR,C=0S_{R,C} = 0 且体力值必须为正数,所以最小值是 11

最终解:

dp1,1dp_{1,1} ,从第 11 行第 11 列走到第 RR 行第 CC 列所需最小体力值。

状态转移:

经过我们前面的分析,我们明白了这是一个逆向 dp。我们从终点往起点推,这一步需要的点数就是下面一步要用的点数的 min\min ,加上当前需要的消耗 (减去获得的体力),且不能小于 11 ,因为最少是 11 ,小于就 game over 了。

转移方程:

dpi,j={max(1,dpi,j+1Si,j) i=Rmax(1,dpi+1,jSi,j) j=Cmax(1,min(dpi+1,j,dpi,j+1)Si,j)dp_{i,j}=\left\{ \begin{aligned} \max(1,dp_{i,j+1}-S_{i,j})\ i=R\\ \max(1,dp_{i+1,j}-S_{i,j})\ j=C\\ \max(1,\min(dp_{i+1,j},dp_{i,j+1})-S_{i,j}) \end{aligned} \right.

核心 Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dp[i][j]=1;
for(int i=r;i>0;i--){
for(int j=c;j>0;j--){
if(i==r&&j==c){
continue;
}
else if(i==r){
dp[i][j]=max(1,dp[i][j+1]-a[i][j]);
}
else if(j==c){
dp[i][j]=max(1,dp[i+1][j]-a[i][j]);
}
else{
dp[i][j]=max(1,min(dp[i][j+1],dp[i+1][j])-a[i][j]);
}
}
}