开始之前先说一句:我校大佬出的题我必须做!
前置知识
真子集:若集合 $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。