zoukankan      html  css  js  c++  java
  • Atcoder 3857 Median Sum

    Problem Statement

    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).

        我们不妨把空集考虑进来,那么最后的答案就是 第 2^(N-1)+1 小的sum。

        显然可以直接O(N^3)dp,最后可以算出和为每个数的集合有多少个。

        然后考虑一下怎么优化这个算法。

        我们可以发现一个集合和它的补集的和总是 所有数的和,这样我们的dp数组肯定是对称的,即最后 f[0] = f[sum of a[]] ....

    所以我们如果要求中位数的话,只需要知道出现过的和的中位数就行了,暴力bitset维护,常数除以了一个32.

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=2000;
    int a[maxn+5],n,now;
    int num[maxn*maxn+5],T;
    bitset<maxn*maxn+maxn> S;
    int main(){
    	scanf("%d",&n),S[0]=1;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&now);
    		S|=S<<now;
    	}
    	for(int i=1;i<=maxn*maxn;i++) if(S[i]) num[++T]=i;
    	printf("%d
    ",num[(T+1)>>1]);
    	return 0;
    }
    

      

  • 相关阅读:
    守护进程、互斥锁、生产者消费者模型
    实现并发编程的基础理论
    udp协议
    进程与进程池
    tcp协议产生-粘包问题的解决方案
    day21面向对象_类
    day16_面向过程编程与模块导入
    day15_函数递归_匿名函数_内置函数
    三、运算符(阶段二)
    二、(续)基础语法--常量、变量和注释(阶段二)
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8782898.html
Copyright © 2011-2022 走看看