问题描述
有一个楼梯有n级台阶,小明站在楼梯最下面,要走到最上面,他只能向上走,每次可以至少 1 级,至多p级。
在每级台阶上有一个权值(一个数),第 i 级的权值为vi,表示小明对于这级台阶的喜爱程度,有的为正,有的为负。
当小明向上走时,他的高兴程度就是所有他踩过的台阶权值之和。
问小明走上楼梯到达最上面的台阶能获得的高兴程度最大是多少?
输入格式
输入的第一行包含两个整数 n,p。
第二行包含n个整数,分别为 v1, v2, ⋯, vn。
输出格式
输出一个整数,表示答案。
样例输入
5 4
3 -1 -3 2 -1
样例输出
4
解题思路
这是一道典型的动态规划题。
我们先定义一个数组dp,dp[i]表示小明走到第一级楼梯时能获得的最大喜爱程度。
但由于这道题中,小明一次能跨上的最大级数是一个变量,所以状态转移方程要用循环来写(我用了一个函数):
int fmax(int x,int y)//x和y分别表示i和p
{
int i;
long long ans=-2e9;//一定要初始化!
for(i=max(0,x-y);i<x;i++)//注意是i<x
ans=max(ans,dp[i]+a[x]);
return ans;
}
还要注意一点:第一级楼梯不一定要走,因为如果第一级楼梯是负数,可能要跳过第一级楼梯。(这一点真的很容易错!绝对不是因为我也错过)
#include<bits/stdc++.h>
using namespace std;
long long dp[1005],a[1005];
int fmax(int x,int y)//x和y分别表示i和p
{
int i;
long long ans=-2e9;//一定要初始化!
for(i=max(0,x-y);i<x;i++)//注意是i<x
ans=max(ans,dp[i]+a[x]);
return ans;
}
int main()
{
int n,i,p;
cin>>n>>p;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)//这里要注意:不用初始化第一个
dp[i]=fmax(i,p);
cout<<dp[n];
return 0;
}