洛谷-P2415 集合求和

1.题目介绍

2.题解

这里我们可以针对单个元素可能出现的子集个数进行统计, 而不是以集合为单位
比如像我们讨论{2,3,4,5}中 2的所有可能出现次数
可以分为:

  1. 2在子集中单独出现
  2. 2在子集中和另一个元素一起出现
  3. 2在子集中和另两个元素一起出现
  4. 2在子集中和剩下所有元素一起出现
    我们发现一共就只有这几种情况,2不可能有其他的出现情况,那么元素2能构成的自己元素和就是
    2(值) * \(2^(4-1)\), 而其他的元素同理(出现次数是相同的),最终就可以获得所有子集元素和 = (元素和)* 出现次数

至于为何\(C_{3}^{0}+C_{3}^{1}+C_{3}^{2}+C_{3}^{3} = 2^{3}\)
可以使用数学归纳法:
1.对于\(C_{0}^{0} = 2^0\)
2.假设对于n = k,\(C_{k}^{0}+C_{k}^{1}+C_{k}^{2}+...+C_{k}^{k} = 2^{k}\)成立
3.对于n = k + 1,
\( \begin{aligned} &C_{k+1}^{0} + C_{k+1}^{1} + C_{k+1}^{2} + \ldots + C_{k+1}^{k} + C_{k+1}^{k+1} \\ &= C_{k+1}^0 + (C_k^0+C_k^1) + (C_k^1+C_k^2) + \ldots + (C_k^{k-1}+C_k^k) + C_{k+1}^{k+1} \\ &= C_{k+1}^0 + 2 \cdot 2^k - C_{k}^0 - C_{k}^k + C_{k+1}^{k+1} \\ &= 2^{k+1} \end{aligned} \)

此时n = k + 1, 所以推理成立!

代码

提供了三种输出方式

#include <iostream>
#include <cmath>
#include <iomanip>

int main() {
    char s;
    int number, n = 0;
    long long result=0;
    while (std::cin >> number) {
        result += number;
        n++;
    }
    std::cout <<  std::fixed <<  std::setprecision(0) << result * pow(2, n-1)  << std::endl;
    //std::cout << (long long) result * pow(2, n - 1) << std::endl; //存在使用e输出法的问题
    printf("%lld\n", (long long)(result * pow(2, n-1) ));
    result *= pow(2, n - 1);
    printf("%lld", result);
    return 0;
}

posted @ 2023-10-21 00:54  DawnTraveler  阅读(33)  评论(0编辑  收藏  举报