Java实现 蓝桥杯VIP 算法训练 步与血(递推 || DFS)

试题 算法训练 步与血

问题描述
  有n*n的方格,其中有m个障碍,第i个障碍会消耗你p[i]点血。初始你有C点血,你需要从(1,1)到(n,n),并保证血量大于0,求最小步数。
输入格式
  第一行3个整数n,m,c,表示棋盘大小、障碍数量和你的血量
  接下来m行,每行描述一个障碍。包含三个整数x y p,分别表示障碍在第x行第y列,消耗血量为p。
输出格式
  如果可以到输出步数,如果不可以,输出"No"。
样例输入
10 10 10
2 8 35
1 10 25
9 9 63
5 6 46
2 6 43
8 7 92
5 3 54
3 3 22
7 9 96
9 10 13
样例输出
18
数据规模和约定
  输入数据中每一个数的范围。
  0<n,m<100,

正常来说应该是一个DFS,四个方向搜索,但是太慢了
,用递推,空间换时间
最小步数可以当作,一个只向右下走的路程

 

import java.util.Scanner;

public class Main {
    //https://blog.csdn.net/a1439775520/article/details/90746562  欢迎进入讨论群
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int c = sc.nextInt();
        int[][] map = new int[n + 1][n + 1];
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 0; i < m; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            int p = sc.nextInt();
            map[x][y] = p;
        }
        sc.close();
        dp[1][1] = c - map[1][1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                int x = i - 1, y = j;
                if (x < 1 || y < 1 || x > n || y > n || dp[x][y] - map[i][j] <= 0) {

                } else {

                    dp[i][j] = Math.max(dp[i][j], dp[x][y] - map[i][j]);
                }

                x = i;
                y = j - 1;
                if (x < 1 || y < 1 || x > n || y > n || dp[x][y] - map[i][j] <= 0) {

                } else {
                    dp[i][j] = Math.max(dp[i][j], dp[x][y] - map[i][j]);
                }
            }
        }
        if (dp[n][n] == 0) {
            System.out.println("No");
        } else {
            System.out.println(2 * (n - 1));
        }

    }
}

posted @ 2020-04-30 09:01  南墙1  阅读(69)  评论(0编辑  收藏  举报