AtCoder C - Median Sum //bitset 01背包优化

 AtCoder C - Median Sum //bitset 01背包优化

C - Median Sum


Time limit : 2sec / Memory limit : 512MB

Score : 700 points

Problem Statement

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

Copy

3
1 2 1

Sample Output 1

Copy

2

In this case, S=(1,1,2,2,3,3,4). Its median is S4=2.


Sample Input 2

Copy

1
58

Sample Output 2

Copy

58

In this case, S=(58).

题意:给一个数组A,求出所有的subsequences的和,再sort,求出中间那个和。

如果含空集,那么一个subsequence x一定有对应的(A-x),那么再最中间的两个subsequence一定是最接近sum/2的,因为没有0,所以最中间那个比sun/2大,问题就转化为01背包。

此题,V=4e6,N=2e3,VN=8e9,会超时,用bitset优化,(会跑的快32或64倍- - )这样就可以过。

因为dp[i]=max(dp[i],dp[i-ai]),那么左移的操作就可以做到这个目的。

比如101011,ai=3,101011<<3=101011000,101011000|101011=10111011就相当于用ai更新了一次。

#include
using namespace std;
#define LL long long
const LL mod = 1000000007;
const int MX = 2e3+1;
bitsetbs;
int main(){
    bs[0]=1;
    int n,s=0,sc;scanf("%d",&n);for(int i=1;i<=n;i++){
        scanf("%d",&sc);bs=bs|(bs<

 

你可能感兴趣的:(dp,stl)