原题链接:https://beta.atcoder.jp/contests/agc020/tasks/agc020_c
Median Sum
Problem Statement
You are given N N integers .
Consider the sums of all non-empty subsequences of
A
A
. There are
such sums, an odd number.
Let the list of these sums in non-decreasing order be S1,S2,⋯,S2N−1 S 1 , S 2 , ⋯ , S 2 N − 1 .
Find the median of this list, S2N−1 S 2 N − 1 .
Constraints
1≤N≤2000
1
≤
N
≤
2000
1≤Ai≤2000
1
≤
A
i
≤
2000
All input values are integers.
Input
Input is given from Standard Input in the following format:
N N
Output
Print the median of the sorted list of the sums of all non-empty subsequences of
A
A
.
Sample Input 1
3
1 2 1
Sample Output 1
2
In this case, . Its median is S4=2 S 4 = 2 .
Sample Input 2
1
58
Sample Output 2
58
In this case, S=(58) S = ( 58 ) .
题目大意
输入一个数组 A1,A2,⋯,AN A 1 , A 2 , ⋯ , A N 。
考虑所有 2N−1 2 N − 1 个非空子集,每个子集的权值是包含的所有元素之和。问这 2N−1 2 N − 1 个非空子集的权值的中位数是什么?
题解
虽然题目不让我考虑空集,但我偏要考虑。。。
加上空集的话, 2N 2 N 个集合刚好可以两两匹配互为补集,这样 2N 2 N 个子集的中位数就是 sum2 s u m 2 ,去掉空集以后,中位数就是大于等于 sum2 s u m 2 的第一个子集。
题解
#include<bits/stdc++.h>
using namespace std;
const int M=2005;
int n,x,sum;
bitset<M*M>dp;
void in(){scanf("%d",&n);}
void ac()
{
dp[0]=1;
for(int i=1;i<=n;++i)scanf("%d",&x),dp|=dp<<x,sum+=x;
for(int i=sum+1>>1;i<=sum;++i)if(dp[i])printf("%d",i),exit(0);
}
int main(){in();ac();}