2021年庐阳区青少年信息学科普日真题- 跳跃(jump)

题目描述

猴子的正上方,每1米处,都有一个桃子,一共有N个桃子,每个桃子都有其能量值,摘下这个桃子吃下就获得了这个能力值。猴子每跳1米会消耗1个点能量,在能量值允许的下,它可以跳到任何一个可以到达的高度,并且将这个高度及以下高度的桃子摘下吃掉。确保猴子初始的能量一定可以摘下所有的桃子。求该猴子摘下吃掉所有的桃子后,保留最多的能量值

输入格式

第一行 两个整数N和M,表示桃子的数量和猴子的初始能量

第二行,N个非负整数,依次描述从下向上描述各桃子的能量值。

输出格式

一个整数,意义如题所述。

输入输出样例

cpp 复制代码
输入样例1:
3 2
2 2 2


输出样例1:
4

说明

1<=N <=2000000


【解析】

如果这道题你们复制本代码,提示超时的话,请使用scanf/printf进行输入输出,因为本题数据量还是很大的。

1:本题关键字 "最多",一般几种算法:贪心、二分、搜索、动规。

2:贪心不对,因为就样例,贪心是不成立的。 二分不适合此题;搜索更不行数据太多;只能想动态规划了。

贪心不对,是因为你总想着,能跳多高就跳多高。比如样例,初始能量2,你一下子就跳2个桃子。还不如只跳第一个桃子,不信去试试。

所以本题的策略是:第i个桃子应该是被下面某个最矮的桃子摘下的,因为从最矮的桃子跳上来到第i个桃子,然后直接掉下去,顺手摘掉 i 下面的桃子。

所以状态定义:dp[i] 表示摘完第i个桃子的最大能量值

状态转移方程:dp[i]=max(dp[i], dp[ 0~i-1 ] >= i + sum[i] - sum[j] - i )

dp[ 0~i-1 ] >= i 表示 满足第一次大于 i 的桃子下标

cpp 复制代码
#include <iostream>
using namespace std;
const int N=2000010;
long long  a[N];
long long dp[N];//摘下第i个桃子的能量值 dp[i]
//dp[i]=min(dp[1~i-1])+a[i]-i
long long sum[N];
int main()
{
    int n,m;
    cin>>n>>m;
    dp[0]=m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
    }
    int j=0;
    for(int i=1;i<=n;i++){
        while(dp[j]<i){
            j++;
        } 
        dp[i]=max(dp[i],dp[j]+sum[i]-sum[j]-i);
    }
    cout<<dp[n];
    return 0;
}
相关推荐
快乐zbc20 小时前
【C++ 基础】:给定一个指针 p,你能判断它是否指向合法的对象吗?
c++
sulikey21 小时前
C++类和对象(下):初始化列表、static、友元、内部类等核心特性详解
c++·static·初始化列表·友元·匿名对象·内部类·编译器优化
oioihoii1 天前
C++网络编程:从Socket混乱到优雅Reactor的蜕变之路
开发语言·网络·c++
程序员东岸1 天前
《数据结构——排序(中)》选择与交换的艺术:从直接选择到堆排序的性能跃迁
数据结构·笔记·算法·leetcode·排序算法
程序员-King.1 天前
day104—对向双指针—接雨水(LeetCode-42)
算法·贪心算法
笨鸟要努力1 天前
Qt C++ windows 设置系统时间
c++·windows·qt
神仙别闹1 天前
基于C++实现(控制台)应用递推法完成经典型算法的应用
开发语言·c++·算法
Ayanami_Reii1 天前
进阶数据结构应用-一个简单的整数问题2(线段树解法)
数据结构·算法·线段树·延迟标记
listhi5201 天前
基于改进SET的时频分析MATLAB实现
开发语言·算法·matlab
Keep_Trying_Go1 天前
基于Zero-Shot的目标计数算法详解(Open-world Text-specified Object Counting)
人工智能·pytorch·python·算法·多模态·目标统计