AGC020C Median Sum

本文深入解析AtCoder竞赛中的子集和中位数问题,介绍了一种巧妙的方法来找到所有非空子集和的中位数,通过将子集与其补集配对,利用位运算和bitset数据结构,高效地解决了这一挑战。

原题链接:https://beta.atcoder.jp/contests/agc020/tasks/agc020_c

Median Sum

Problem Statement

You are given N N integers A1,A2,,AN.

Consider the sums of all non-empty subsequences of A A . There are
2N1 such sums, an odd number.

Let the list of these sums in non-decreasing order be S1,S2,,S2N1 S 1 , S 2 , ⋯ , S 2 N − 1 .

Find the median of this list, S2N1 S 2 N − 1 .

Constraints

1N2000 1 ≤ N ≤ 2000
1Ai2000 1 ≤ A i ≤ 2000
All input values are integers.

Input

Input is given from Standard Input in the following format:

N N

A1 A2  AN

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, S=(1,1,2,2,3,3,4). 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

考虑所有 2N1 2 N − 1 个非空子集,每个子集的权值是包含的所有元素之和。问这 2N1 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();}
### 归一化方法 SUMMedian 的选择标准及适用场景 归一化是一种常用的数据预处理技术,用于将数据缩放到一个特定的范围(如 [0, 1] 或 [-1, 1])。在实际应用中,根据数据特性和模型需求,可以选择不同的归一化方法。以下是关于 SUMMedian 两种归一化方法的选择标准及适用场景的详细分析。 #### 1. **SUM 归一化** SUM 归一化是指将数据中的每个值除以该列所有值的总和,使得每一列的值加起来等于 1。公式如下: \[ x_{\text{normalized}} = \frac{x}{\sum x} \] - **适用场景**: - 数据本身具有加性特性,且需要保持各部分的比例关系时[^2]。 - 特别适用于概率分布或频率数据的处理,例如文本分类任务中的词频向量[^2]。 - 当模型对数据的绝对大小不敏感,而更关注相对比例时。 - **优点**: - 能够有效保留数据的比例信息。 - 对于某些机器学习算法(如基于距离的算法),能够避免某一特征因数值较大而主导模型训练结果。 - **缺点**: - 如果数据中存在异常值,可能会导致归一化后的结果失真[^3]。 - 不适合处理稀疏数据,因为零值会被压缩到非常小的范围内,可能丢失信息[^2]。 #### 2. **Median 归一化** Median 归一化是基于数据的中位数进行归一化处理。通常的做法是用中位数替换异常值,或者将数据缩放到以中位数为中心的范围。这种归一化方法特别适用于鲁棒标准化场景。 - **适用场景**: - 数据中存在较多异常值或极端值时[^3]。 - 当模型对异常值较为敏感,需要减少其影响时。 - 数据分布不对称,且中位数比均值更能反映数据的中心趋势时。 - **优点**: - 稳健性强,不易受异常值的影响[^3]。 - 能够较好地保留数据的真实分布特性[^3]。 - **缺点**: - 计算复杂度较高,尤其是对于大规模数据集[^3]。 - 需要额外的步骤来检测和处理异常值,增加了实现难度。 #### 示例代码 以下是一个简单的 Python 实现示例,分别展示了 SUMMedian 归一化的应用: ```python import numpy as np from sklearn.preprocessing import normalize # 示例数据 data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # SUM 归一化 sum_normalized = data / data.sum(axis=0) # Median 归一化 median = np.median(data, axis=0) median_normalized = (data - median) / np.max(np.abs(data - median), axis=0) print("SUM Normalized:\n", sum_normalized) print("Median Normalized:\n", median_normalized) ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值