题解 LGP9160 multiset

由 hycqwq 发布

开始之前先说一句:我校大佬出的题我必须做!

前置知识

真子集:若集合 $B$ 是集合 $A$ 的子集且 $A \ne B$,则称 $B$ 为 $A$ 的真子集。

思路

前置定义

令 $|X|$ 为集合 $X$ 的元素个数。

设 $S = \{s_1, s_2, \cdots, s_n\}$ 且 $s_1 \le s_2 \le \cdots \le s_n$。

设 $T = \{t_1, t_2, \cdots, t_{|T|}\}$ 且 $t_1 \le t_2 \le \cdots \le t_{|T|}$。

思路推导

由于题目要求 $T$ 是 $S$ 的子集,所以 $T \ne S$,于是我们需要去掉至少一个数,但在这里,我们要的是最大的 $T$,所以我们只需要去掉一个数,即 $|T| = n - 1$。

首先,我们要知道,直接把 $S$ 中的最大值去掉(即 $T = \{s_1, s_2, \cdots, s_{n - 1}\}$)是符合条件的,但可能不是最小。

我们要使 $T$ 中元素的和最大,那么我们去掉的数肯定是越小越好,但是如果我们去掉了一个在 $S$ 中只有一个的数(设其为 $s_i$),就会导致另外一个以它为前驱的数在 $S$ 中有前驱,但在 $T$ 中没有,是不符合题目条件的,所以我们去掉的数应该是最小的有重复的数。

那如果 $S$ 中没有重复的数呢?那我们去掉的数应该不是任何数的前驱,而只有最大的那个数(即 $s_n$)符合条件。

总结

显然对于第一问,$|T| = n - 1$。

第二问有以下两种情况:

  • 若存在整数 $i < j$ 使 $s_i = s_j$,则 $\sum\limits_{a = 1}^{|T|}t_a = (\sum\limits_{b = 1}^{n}s_b) - s_i$。
  • 否则 $\sum\limits_{a = 1}^{|T|}t_a = \sum\limits_{b = 1}^{n - 1}s_b$.

代码

#include <iostream>
#include <algorithm>
using namespace std;

int n, s[100005];
long long sum = 0;//不开long long见祖宗

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> s[i], sum += s[i];
    sort(s + 1, s + n + 1);//按从大到小排序,否则不好确定是否有重复以及元素的最大值
    for (int i = 2; i <= n; i++)
        if (s[i] == s[i - 1] || i == n)//减去重复的或最大的
        {
            sum -= s[i];
            break;//取了一个直接结束
        }
    cout << n - 1 << " " << sum << endl;//由于只去掉一个元素,所以T的大小为n - 1
    return 0;
}

提交记录:R106306487


暂无评论

发表评论