atcoder:Median Sum【01背包】

传送门
bitset 有点水分,没想到还可以这样优化
对于每个权值v都有一个对应的”补集”t满足 v + t = s u m v+t=sum v+t=sum,就是说集合中找个断点两边两个权值相加都是整个集合的和。
因此可以根据中位数的定义跑一遍01背包找出中位数。
code:

#include
using namespace std;
bitset<5000000>s;
int main(){
    int n,x,sum=0;
    scanf("%d",&n);
    s[0]=1;
    for(int i=0;i<n;i++)
        scanf("%d",&x),s|=s<<x,sum+=x;
    for(int i=(sum+1)>>1;;i++)
    if(s[i]){
            printf("%d",i);
            return 0;
    }
    return 0;
}

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