奶牛的锻炼

奶牛的锻炼

题目描述

奶牛Bessie有N分钟时间跑步,每分钟她可以跑步或者休息。若她在第i分钟跑步,可以跑出D_i米,同时疲倦程度增加1(初始为0)。若她在第i分钟休息,则疲倦程度减少1。无论何时,疲倦程度都不能超过M。另外,一旦她开始休息,只有当疲惫程度减为0时才能重新开始跑步。在第N分钟后,她的疲倦程度必须为0。

输入格式

第一行,两个整数,代表N和M。 接下来N行,每行一个整数,代表D_i。

输出格式

Bessie想知道,她最多能跑的距离。

样例输入

5 2
5
3
4
2
10

样例输出

9

解题思路

采用动态规划的方法,状态数组dp[i] [j]表示在时间i内疲劳值j下能够达到的最远距离。

dp[i] [j]疲劳值为j,那么其一定不会停止,一直是跑步的,则dp[i] [j]=dp[i - 1] [j - 1] + D(i)

需要注意的是dp[i] [0],所求的就是疲劳值为0时的最远距离,来源有两个。

1.疲劳值为 j 时的最远距离到现在休息结束,疲劳值清零时的最远距离

2.上一分钟就是在休息,到现在这一分钟接着休息,这一分钟不能跑步,跑步后疲劳值就不能清零

dp[i] [0]=max(dp[i] [0],dp[i-1] [0],dp[i - j] [j])其中有求最大值时有dp[i] [0]是为了确保dp[i] [0]一直是最大值。

代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

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

        int N = scanner.nextInt();
        int M = scanner.nextInt();

        ArrayList<Integer> D=new ArrayList<>();
        D.add(0);

        for(int i=0;i<N;i++){
            D.add(scanner.nextInt());
        }

        int[][] dp=new int[10001][501];
        for(int i=0;i<=10000;i++)
            Arrays.fill(dp[i],0);
        for(int i=1;i<=N;i++){
            for(int j=1;j<=M;j++){
                dp[i][j] = dp[i - 1][j - 1] + D.get(i);
                if (i - j >= 0)//休息
                {
                    //需要与dp[i][0]对比,需要确保一直输出的最大的值,
                    //若是采用dp[i][0]=dp[i-1][0]>dp[i - j][j]?dp[i-1][0]:dp[i - j][j]; dp[i][0]不会一直是最大值,会被覆盖
                    dp[i][0] = dp[i][0]>dp[i - j][j]?dp[i][0]:dp[i - j][j];
                    dp[i][0]=dp[i][0]>dp[i-1][0]?dp[i][0]:dp[i-1][0];

                }
            }
        }
        System.out.println(dp[N][0]);

    }
}
posted @ 2025-03-09 17:09  狐狸胡兔  阅读(26)  评论(0)    收藏  举报