(洛谷)P4995 跳跳!

你是一只小跳蛙,你特别擅长在各种地方跳来跳去。
在这里插入图片描述

为了给小 F 展现你超级跳的本领,你决定跳到每个石头上各一次,并最终停在任意一块石头上,并且小跳蛙想耗费尽可能多的体力值。

当然,你只是一只小跳蛙,你只会跳,不知道怎么跳才能让本领更充分地展现。

不过你有救啦!小 F 给你递来了一个写着 AK 的电脑,你可以使用计算机程序帮你解决这个问题,万能的计算机会告诉你怎么跳。

那就请你——会写代码的小跳蛙——写下这个程序,为你 NOIp AK 踏出坚实的一步吧!

输入格式
输入一行一个正整数 nn,表示石头个数。

输入第二行 nn 个正整数,表示第 ii 块石头的高度 h_ih
i

输出格式
输出一行一个正整数,表示你可以耗费的体力值的最大值。
输入 #1复制
2
2 1
输出 #1复制
5
输入 #2复制
3
6 3 5
输出 #2复制
49
说明/提示
样例解释
两个样例按照输入给定的顺序依次跳上去就可以得到最优方案之一。

在这里插入图片描述
巩固下贪心算法,这个题当时第一次做的时候有五个测试点没过,原因后来找到了算体力要用long long型数据储存,因为平方太大,只能用这个了。。。

看到比较大的数据还是果断用long吧

其实贪心的本质就是部分最优解,从而达到整体的最优解。

这一题要消耗体力最多,那么我只要跳的每一步都要尽可能的消耗体力,这就是局部的最优解。试想,每一步消耗的体力都是最多的,那么最后消耗体力的总和就是最多的。

1.但要注意第一步和后面的步数是不一样的(类似分段函数),所以我们先输入完所有石头的高度之后,先按照从大到小对高度排序,这个时候排在数组第一位的就是高度最大的,这个时候先算第一个,后面的步数再分来来算。

2.后面要尽可能多的消耗体力,不难理解只需要每一次跳石头消耗体力相差最大就好了,但是如何实现呢?
这里我采用了类似二分的思想,一前一后,计算距离,每次计算都让相应下标增加/减少,当前面的下标大于后面的下标的时候,循环结束

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	int n;
	long long h[301];
	long long sum = 0;//切记用longlong
	int start, end;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> h[i];
	}
	sort(h, h + n,greater<int>());
	start = 0;
	end = n-1;
	sum = sum + h[0] * h[0];//先算第一步消耗的体力
	while (start<end)//类似二分思想,求消耗体力最多最大
	{
		sum = sum + (h[start] - h[end]) * (h[start] - h[end]);
		start++;
		sum = sum + (h[start] - h[end]) * (h[start] - h[end]);
		end--;
	}
	cout << sum;
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值