两题题意大致相同,做法也相同,差别在于最后输出,到底是直接输出dp[1][1](我使用 1,1 点作为起点),还是在dp数组中选择最大值。我因为没考虑清这个问题,两题分别用了另一题的输出方式。。。。
首先在做滑雪的时候,因为测试样例能够遍历全图,所以我直接在最后输出了dp[1][1],然后提交一直WA,后来翻了翻上课的时候的代码,发现最后是要找最大值,才意识到,因为这题是没有规定起点的,所以每次dfs相当于搜完了跟这个起点连通的,而其他不能到的点是另起炉灶的,所以在最后要找dp数组的最大值。
而老鼠奶酪的刚好相反,规定起点必须是(1,1),结果我想都没想就照着滑雪写了代码。。。WA后才想到这里的区别。。。改完就能A了
这两题算是坐标DP的模板基础题,因此在初学的时候,觉得对比下是有必要的,而且老鼠题还附加了别的条件,也算是不那么基础的基础题吧?
下面两题代码:
POJ 1088
#include<cstdio>
#include<algorithm>
using namespace std;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {1, -1, 0, 0};
const int N = 1e3;
int n, m, ans = 0;
int dp[N][N], a[N][N];
int dfs(int x, int y){
if(dp[x][y] > 0) return dp[x][y];
dp[x][y] = 1;
for(int i = 0; i < 4; i++){
int xx = x + dx[i];
int yy = y + dy[i];
if(xx < 1 || yy < 1 || xx > n || yy > m || a[xx][yy] >= a[x][y]) continue;
dp[x][y] = max(dp[x][y], dfs(xx, yy) + 1);
}
return dp[x][y];
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(dp[i][j] == 0) ans = max(ans, dfs(i, j));
}
}
printf("%d\n", ans);
return 0;
}
HDU 1078
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static Scanner sc = new Scanner(System.in);
static int [][] dp = new int[105][105];
static int [][] map = new int[105][105];
static int dx[] = {0, 0, -1, 1};
static int dy[] = {1, -1, 0, 0};
static int n,k,res;
static int dfs(int x, int y) {
if(dp[x][y] > 0) return dp[x][y];
int max = 0;
for(int i = 0; i < 4; i++){
for(int j = 1; j <= k; j++) {
int xx = x + dx[i] * j;
int yy = y + dy[i] * j;
if(xx < 1 || yy < 1 || xx > n || yy > n || map[xx][yy] <= map[x][y]) continue;
max = Math.max(max, dfs(xx, yy));
}
}
return dp[x][y] = max + map[x][y];
}
public static void main(String[] args) {
while(sc.hasNext()) {
n = sc.nextInt(); k = sc.nextInt();
if(n == -1 && k == -1) break;
res=0;
for(int i = 1; i <= n; i++) {
Arrays.fill(dp[i], 0);
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
map[i][j] = sc.nextInt();
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(dp[i][j] == 0)
res = Math.max(res, dfs(i,j));
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
System.out.print(dp[i][j]+" ");
}
System.out.println();
}
System.out.println(res);
}
System.exit(0);
}
}