问题描述
zxa有一个集合A={a1,a2,⋯,an},n表示集合A的元素个数,这个集合明显有(2n−1)个非空子集合。 对于每个属于A的子集合B={b1,b2,⋯,bm}(1≤m≤n),m表示集合B的元素个数,zxa定义它的价值是min(b1,b2,⋯,bm)。 zxa很好奇,如果令Sodd表示集合A的所有含奇数个元素的非空子集合的价值之和,Seven表示集合A的所有含偶数个元素的非空子集合的价值之和,那么∣Sodd−Seven∣是多少,你能帮助他吗?
输入描述
第一行有一个正整数T,表示有T组数据。 对于每组数据: 第一行有一个正整数n,表示集合有n个元素。 第二行有n个互异的正整数,表示集合的元素a1,a2,⋯,an。 每一行相邻数字之间只有一个空格。 1≤T≤100,1≤n≤30,1≤ai≤109
输出描述
对于每组数据,输出一行,包含一个非负整数,表示∣Sodd−Seven∣的值。
输入样例
3 1 10 3 1 2 3 4 1 2 3 4
输出样例
10 3 4
Hint
对于第一组样例,A={10},它只有一个含奇数个元素的子集合{10},没有含偶数个元素的子集合,所以Sodd=10,Seven=0,∣Sodd−Seven∣=10。 对于第二组样例,A={1,2,3},它有四个含奇数个元素的子集合{1},{2},{3},{1,2,3},有三个含偶数个元素的子集合{1,2},{2,3},{1,3},所以Sodd=1+2+3+1=7,Seven=1+2+1=4,∣Sodd−Seven∣=3
分析:其实这个题目看下题目数据都应该能猜出规律。就是输出为原来序列中最大那个数。
证明如下:
我们将一个序列从小到大排序后为 a1,a2,a3.....,an.那么其所有非空子集可以分为{an}和S.S包括了除{an}这个集合外其余所有非空子集。那么S中的集合就可以分为两类A,B。一类A是子集中包含an的,一类B是不包含an的。并且。这两类可以相互对应。也就是说A中的任意一个子集去掉an都能在B中找到相同的子集,并且B中任意一个子集加上an都能在A中找到相同子集。那么说明A,B两个集合包含的子集个数是相同的。并且相对应的两个子集大小奇偶不同(这个肯定了,一个子集要比另一个子集多一个,肯定是一奇一偶)。并且相对应的两个子集其贡献是相同的,因为都是min(子集),所以相互抵消。那么S中的所有集合总贡献都相互抵消。那么所有非空子集就只剩下了{an}.那么答案就是an.
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int main() { int t,n,ans; cin >> t; while(t--) { scanf("%d",&n); ans = 0; int a; for(int i = 0 ;i < n ; i ++) { scanf("%d",&a); if( a > ans) ans = a; } printf("%d\n",ans); } return 0; }