P2415 集合求和(一道洛谷好题鸭)(虽然可以水过,但有必研究DP)
此题坑点:
-
结果必须要用long long存,int存不下
-
如果想要像
cout<<sum*pow(2,num-1)
这样在输出时计算会错:
long long在计算过程被隐式转换成了double,需要用强制类型转换转换回long long输出。 -
集合论和排列组合公式初中还没学
题目描述
给定一个集合s(集合元素数量<=30),求出此集合所有子集元素之和。
分析
我们来看一个例子: \{1,2,3\}{1,2,3}
可以得到,它的所有非空子集为 \{1,2,3\}{1,2,3} \{1,2\}{1,2}\{2,3\}{2,3} \{1,3\}{1,3} \{1\}{1} \{2\}{2} \{3\}{3}
现在来分析每一个元素在每一个子集中出现的个数:
11出现了44次,22出现了44次,33出现了44次
我们猜测:对于一个有限集合AA,它的每一个元素在AA的所有子集中出现的个数是{2^{\operatorname{card}(A)-1}}2card(A)−1
证明:(集合论纯自学,可能格式有误, 请别在意QAQ)
设B\subseteq AB⊆A, 记n=\operatorname{card}(A)n=card(A), ss为AA中所有元素之和
当\operatorname{card}(B)=1card(B)=1时,显然,每个元素在BB中出现11次;
当\operatorname{card}(B)=2card(B)=2时,保证一个元素必选,在剩余的n-1n−1个元素中选择11个元素,共C^1_{n-1}=n-1Cn−11=n−1种情况,故每个元素在BB中出现C^1_{n-1}=n-1Cn−11=n−1次;
当\operatorname{card}(B)=3card(B)=3时,保证一个元素必选,在剩余的n-1n−1个元素中选择22个元素,共C^2_{n-1}=\frac{(n-1)!}{2(n-1-2)!}=\frac{(n-1)(n-2)}{2}Cn−12=2(n−1−2)!(n−1)!=2(n−1)(n−2)种情况,故每个元素在BB中出现共C^2_{n-1}=\frac{(n-1)(n-2)}{2}Cn−12=2(n−1)(n−2)次;
当\operatorname{card}(B)=kcard(B)=k时,保证一个元素必选,在剩余的n-1n−1个元素中选择k-1k−1个元素,共C^{k-1}_{n-1}Cn−1k−1种情况,故每个元素在BB中出现共C^{k-1}_{n-1}Cn−1k−1次;
那么,每个元素在AA的每一个子集中出现的个数为: \sum\limits_{i=1}^{n}C^{i-1}_{n-1}=2^{n-1}i=1∑nCn−1i−1=2n−1 ①
AA的所有子集元素之和为s\times2^{n-1}s×2n−1
故代码如下:
#include<bits/stdc++.h> using namespace std; int main(){ long long tmp,num=0,sum=0; while(cin>>tmp){ sum+=tmp; num++; }//读入集合元素个数num和元素和sum cout<<(long long)(sum*pow(2,num-1)); //必须显式地转换为long long输出 }
①: 不懂为什么\sum\limits_{i=1}^{n}C^{i-1}_{n-1}=2^{n-1}i=1∑nCn−1i−1=2n−1的可以看一下数学归纳法证明:
将用到的性质公式:
- C^m_n=C^{m-1}_{n-1}+C^{m}_{n-1}Cnm=Cn−1m−1+Cn−1m
- C^n_n=C^0_n=1Cnn=Cn0=1
\sum\limits_{i=0}^{n}C^{i}_{n}=2^{n}i=0∑nCni=2n
证明:
1)当n=1n=1时:
\sum\limits_{i=0}^{n}C^{i}_{n}=C^0_1+C^1_1=2=2^1i=0∑nCni=C10+C11=2=21
等式成立。
2)假设当n=k(k\in N_+)n=k(k∈N+)时\sum\limits_{i=0}^{n}C^{i}_{n}=2^{n}i=0∑nCni=2n 成立, 即\sum\limits_{i=0}^{k}C^{i}_{k}=2^{k}i=0∑kCki=2k
那么当n=k+1n=k+1时:
\text{\ \ \ \ } \sum\limits_{i=0}^{k+1}C^{i}_{k+1}i=0∑k+1Ck+1i
=C^{0}_{k+1}+C^{1}_{k+1}+C^{2}_{k+1}+...+C^{k}_{k+1}+C^{k+1}_{k+1}=Ck+10+Ck+11+Ck+12+...+Ck+1k+Ck+1k+1
=C^{0}_{k+1}+(C^{0}_{k}+C^{1}_{k})+(C^{1}_{k}+C^{2}_{k})+...+(C^{k-1}_{k}+C^{k}_{k})+C^{k+1}_{k+1}=Ck+10+(Ck0+Ck1)+(Ck1+Ck2)+...+(Ckk−1+Ckk)+Ck+1k+1
=C^{0}_{k}+(C^{0}_{k}+C^{1}_{k})+(C^{1}_{k}+C^{2}_{k})+...+(C^{k-1}_{k}+C^{k}_{k})+C^{k}_{k}=Ck0+(Ck0+Ck1)+(Ck1+Ck2)+...+(Ckk−1+Ckk)+Ckk
=2(C^0_k+C^1_k+C^2_k+...+C^k_k)=2(Ck0+Ck1+Ck2+...+Ckk)
=2\sum\limits_{i=0}^{k}C^{i}_{k}=2i=0∑kCki
=2\times2^k=2×2k
=2^{k+1}=2k+1
此时等式依然成立。假设成立。
故\sum\limits_{i=0}^{n}C^{i}_{n}=2^{n}i=0∑nCni=2n
由此可以得到,\sum\limits_{i=1}^{n}C^{i-1}_{n-1}=2^{n-1}i=1∑nCn−1i−1=2n−1