Luogu P4995 题解

题目

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;
}
原文地址:https://www.cnblogs.com/Node-Sans-Blog/p/13736635.html