AtCoder3857:Median Sum (Bitset优化背包&&对称性求中位数)

Median Sum

You are given N integers A1A2, ..., 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 S1S2, ..., 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
",i);
               break;
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/8540923.html