题目
https://www.luogu.com.cn/problem/P4995
思路
加入上一次选择的石头的高度为 $ h_i $,这次选择的石头的高度为 (h_j),然后选择能使得 ((h_i - h_j)^2) 最大的石头就行了。
证明
这个题目用数学归纳法证明就可以了。
首先当我们选择第一块石头的时候,我们按照上面的策略,会选择最高的石头,那么显然在 (i=1) 的时候我们会得到最大的答案。
接下来我们假设选择第 (i) 块石头的时候,上面的贪心原则是正确的,我们设此时的耗费的体力值为 (s)。那么在选择第 (i+1) 块石头的时候,按照上面的策略,此时耗费的体力值为 $ s + max((h_i - h_j)^2) $,显然这么做耗费的体力值在选择第 (i+1) 块石头的时候也是最大的。
所以,我们这么贪心是正确的。
代码(记得开 long long
!)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
int main()
{
long long n, arr[305];
scanf("%lld", &n);
for (int i = 1; i <= n; ++i)
scanf("%lld", &arr[i]);
long long last = 0, sum = 0, maxn, maxPos;
bool flag[305];
memset(flag, 0, sizeof(flag));
for (int i = 1; i <= n; ++i)
{
maxn = -1;
for (int j = 1; j <= n; ++j)
{
if (!flag[j] && (arr[j] - last) * (arr[j] - last) > maxn)
{
maxn = (arr[j] - last) * (arr[j] - last);
maxPos = j;
}
}
flag[maxPos] = true;
sum += maxn;
last = arr[maxPos];
}
printf("%lld
", sum);
return 0;
}