day21 1015 摘花生 (线性DP)

1015. 摘花生

Hello Kitty想摘点花生送给她喜欢的米老鼠。

她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。

地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。

Hello Kitty只能向东或向南走,不能向西或向北走。

问Hello Kitty最多能够摘到多少颗花生。
在这里插入图片描述
输入格式
第一行是一个整数 T T T,代表一共有多少组数据。

接下来是 T T T组数据。

每组数据的第一行是两个整数,分别代表花生苗的行数 R R R和列数 C C C

每组数据的接下来 R R R行数据,从北向南依次描述每行花生苗的情况。每行数据有 C C C个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目 M M M

输出格式
对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。

数据范围
1 ≤ T ≤ 100 , 1≤T≤100, 1T100,
1 ≤ R , C ≤ 100 , 1≤R,C≤100, 1R,C100,
0 ≤ M ≤ 1000 0≤M≤1000 0M1000
输入样例:

2
2 2
1 1
3 4
2 3
2 3 4
1 6 5

输出样例:

8
16

思路:

Hello Kitty只能向东或向南走,不能向西或向北走,也即只能向右或者向下走。

这是一个典型的线性dp问题。

我们把走到一个点看做一个状态,对Hello Kitty来说,走到一个点只有两种方式,一种是从上面下来走到该点,另一种是从左边过来走到该点。即要到达点 ( i , j ) (i,j) (i,j),要么是从 ( i − 1 , j ) (i−1,j) (i1,j)走到 ( i , j ) (i,j) (i,j),要么是从点( i , j − 1 ) i,j−1) i,j1)走到 ( i , j ) (i,j) (i,j)

我们用 d p [ i ] [ j ] dp[i][j] dp[i][j]来代表走到点 ( i , j ) (i,j) (i,j)一共摘到的花生。我们需要走到 ( n − 1 , m − 1 ) (n - 1,m - 1) (n1,m1),所以可以得到状态转移方程: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] ) , d p [ i ] [ j − 1 ] ) ) + a r r [ i ] [ j ] dp[i][j]=max(dp[i−1][j]),dp[i][j−1]))+arr[i][j] dp[i][j]=max(dp[i1][j]),dp[i][j1]))+arr[i][j]。根据转移方程,我们可以推出走到 ( n − 1 , m − 1 ) (n - 1,m - 1) (n1,m1)处摘到的最多花生。

Java代码

import java.util.Scanner;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();

        //共需要处理T组数据
        while(T-- != 0){
    
    
            int n = scanner.nextInt();
            int m = scanner.nextInt();
            int[][] arr = new int[n][m];
            int[][] dp = new int[n][m];
            //读入一组数据
            for(int i = 0;i < n;i++){
    
    
                for(int j = 0; j < m;j++){
    
    
                    arr[i][j] = scanner.nextInt();
                }
            }

            //1. 初始化dp
            dp[0][0] = arr[0][0];
            //第一行的只能从左边过来
            for(int j = 1;j < m;j++) dp[0][j] = dp[0][j - 1] + arr[0][j];
            //第一列只能从上面下来
            for(int i = 1;i < n;i++) dp[i][0] = dp[i - 1][0] + arr[i][0];
            //2. 计算dp
            for(int i = 1;i < n;i++){
    
    
                for(int j = 1;j < m;j++){
    
    
                    dp[i][j] = Math.max(dp[i - 1][j],dp[i][j - 1]) + arr[i][j];
                }
            }
            System.out.println(dp[n- 1][m - 1]);
        }
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/YouMing_Li/article/details/113916273
今日推荐