AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)
Median Sum
You are given N integers A1, A2, ..., AN.
Consider the sums of all non-empty subsequences of A. There are 2N−1 such sums, an odd number.
Let the list of these sums in non-decreasing order be S1, S2, ..., S2N−1.
Find the median of this list, S2N−1.
Constraints
- 1≤N≤2000
- 1≤Ai≤2000
- All input values are integers.
Input
Input is given from Standard Input in the following format:
N A1 A2 … AN
Output
Print the median of the sorted list of the sums of all non-empty subsequences of A.
Sample Input 1
3 1 2 1
Sample Output 1
2
In this case, S=(1,1,2,2,3,3,4). Its median is S4=2.
Sample Input 2
1 58
Sample Output 2
58
In this case, S=(58).
题意:给定N个数,有2^N-1种非空组合,求这些组合的和排序后的中位数。
思路:由对称性,知道中位数略大于Sum/2,所以我们从(Sum+1)/2后面所有的可能中,选择最近的一个。(证明见下面。)
具体实现:需要得到背包结果有哪些可能性,这个只需要Bitset加速一下即可得到。
证明:见前辈写的,很清晰,只要利用对称性即可。ZZZZone
#include<bitset> #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxn=2002; bitset<maxn*maxn+10>s; int main() { int N,x,ans; while(~scanf("%d",&N)){ s.reset(); ans=0; s[0]=1; for(int i=1;i<=N;i++){ scanf("%d",&x); s|=(s<<x); ans+=x; } for(int i=(ans+1)/2;;i++){ if(s[i]){ printf("%d\n",i); break; } } } return 0; }
It is your time to fight!