每个元素会出现在一半子集中,因此答案是元素总和乘以 2 的 n-1 次方。
OJ: luogu
题目 ID: P2415
难度:入门
标签:数学集合python
日期: 2026-07-15 21:22
题意
给定一个集合,求所有子集中所有元素的和。
思路
设集合有 n 个元素。对任意一个元素来说,其他 n-1 个元素都可以选或不选,因此包含它的子集有:
text
2^(n-1)所以每个元素都会被加 2^(n-1) 次,答案就是:
text
sum(numbers) * 2^(n-1)这题关键是数学计数,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:输入没有给数量时,可以直接input().split()读取整行元素。/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md:Python 整数不会溢出,能直接处理本题答案范围。sum(numbers)求列表总和。2 ** k表示。
代码
python
numbers = list(map(int, input().split()))
answer = sum(numbers) * (2 ** (len(numbers) - 1))
print(answer)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int a[35]; // 集合元素
int n; // 元素个数
int main() {
int x;
while (cin >> x) a[++n] = x;
// 每个元素在 2^(n-1) 个子集中出现
long long sum = 0;
for (int i = 1; i <= n; i++) sum += a[i];
long long ans = sum * (1LL << (n - 1)); // 等价于 sum * 2^(n-1)
cout << ans;
return 0;
}Pythonic 写法
子集和位运算:
python
nums = list(map(int, input().split()))
print(sum(nums) << (len(nums) - 1))复杂度
设元素个数为 n,时间复杂度是
总结
不要枚举所有子集。换个角度统计每个元素贡献次数,就能把指数问题变成一次求和。