问题描述
这个游戏有n个关卡,第i个关卡你可以得到V[i]的金钱。但是每打一个关卡就会损失P的金钱。
当你打完第i个关卡的时候,可以选择打第i+1...min{i+m,n}个关卡。
你必须从第1关打起,问你打完第n个关卡时最多可以得到多少金钱?
输入格式
第一行n,m,P。
第二行n个整数V[i]。
输出格式
输出一行表示最多可以获得的金钱。
样例输入
2 2 2
1 2
样例输出
-1
数据规模和约定
0<m≤n≤1000
其余所有数字都是不超过1,000,000,000的非负整数。
问题分析
这道题就是动态规划爬楼梯的一道变形题,把能走的步数变成了1~m步,剩下的按照题意就能做出来了。代码如下:
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();
Long p=scanner.nextLong();
//每关能拿到的金币
Long[] v=new Long[n+1];
//存储每关最多能拿到的金币
Long[] dp=new Long[n+1];
for (int i = 1; i <= n; i++) {
v[i]=scanner.nextLong();
}
//第一关一定要过,算出第一关能拿到的金币
dp[1]=v[1]-p;
//找到每一关能拿到最多的金币
for (int i = 2; i <= n; i++) {
Long max=Long.MIN_VALUE;
//每关的最大值都是从前面闯过的关中选最大值,但最多只能往前看m关所以j>=i-m,同时也不能看到-1关去所以j>0
for (int j=i-1; j >0&&j>=i-m ; j--) {
max=Math.max(max,dp[j]);
}
//找到了前面的最大值,算出当前关的最大值
dp[i]=max+v[i]-p;
}
System.out.println(dp[n]);
}
}