最优走楼梯

问题描述

  有一个楼梯有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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值