解题思路

-
安全指数 y i y_i yi 和结果 r e s u l t i result_i resulti:
- 表中的第一列是学生的安全指数 y i y_i yi。
- 第二列是他们的实际挂科结果 r e s u l t i result_i resulti,0 表示挂科,1 表示未挂科。
-
阈值 θ \theta θ:
- 后面的几列代表不同的阈值 θ \theta θ,包括 θ = 0 \theta = 0 θ=0, θ = 1 \theta = 1 θ=1, θ = 3 \theta = 3 θ=3, θ = 5 \theta = 5 θ=5, θ = 7 \theta = 7 θ=7。
- 在每个阈值下,根据预测函数
predict(y, theta),判断是否正确预测了同学的挂科情况。
-
预测正确数:
- 最后一行是该阈值下预测正确的个数。比如在 θ = 1 \theta = 1 θ=1 时,正确预测的数量是 5 个。
变化的规律与差值数组的引入
-
图片中的黄色部分表示,在不同阈值 θ \theta θ 之间切换时,唯一发生变化的预测结果。这部分就是在当前阈值下与该阈值相等的 y i y_i yi 所对应的预测结果发生了变化。例如,在 θ = 1 \theta = 1 θ=1 切换到 θ = 3 \theta = 3 θ=3 时,只有 y = 1 y = 1 y=1 的预测结果发生了变化。
-
变化的规律:
- 当阈值从
θ
i
−
1
\theta_{i-1}
θi−1 变为
θ
i
\theta_i
θi 时,只有与
θ
i
−
1
\theta_{i-1}
θi−1 相等的
y
i
y_i
yi 的部分会发生变化。其具体变化方式遵循公式:
n u m i = n u m i − 1 + Δ num_i = num_{i-1} + \Delta numi=numi−1+Δ
其中 Δ \Delta Δ 是当前阈值下 r e s u l t = 0 result = 0 result=0 和 r e s u l t = 1 result = 1 result=1 之间的差值。
- 当阈值从
θ
i
−
1
\theta_{i-1}
θi−1 变为
θ
i
\theta_i
θi 时,只有与
θ
i
−
1
\theta_{i-1}
θi−1 相等的
y
i
y_i
yi 的部分会发生变化。其具体变化方式遵循公式:
-
差值数组的作用:
- 差值数组
diff的引入,是为了更高效地计算每个阈值下的预测正确数量。在初始状态下,我们可以通过直接计算来获得第一个阈值的正确预测数。 - 对于后续的阈值,通过差值数组
diff,可以利用上一个阈值的正确预测数进行增量更新,而不必重新遍历所有学生的安全指数。这就显著优化了时间复杂度,从 O ( m 2 ) O(m^2) O(m2) 降低到 O ( m ) O(m) O(m)。
- 差值数组
代码
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
using namespace std;
int m;
int predict(int y, int t)
{
return y >= t;
}
void update_diff(map<int, int>& diff, int y, int result) {
if (result == 0)
diff[y]++;
else
diff[y]--;
}
int main() {
cin >> m;
vector<int> y(m), result(m), theta(m);
map<int, int> diff;
// 1. 计算diff数组:统计0/1个数差值
for (size_t i = 0; i < m; i++) {
cin >> y[i] >> result[i];
update_diff(diff, y[i], result[i]); // 访问不存在的键时,map 会自动创建该键并默认为 0
}
// 2. 计算首轮预测正确数
auto it = diff.begin();
for (size_t i = 0; i < m; i++) {
theta[0] += predict(y[i], it->first) == result[i];
}
// 3. 利用diff数组计算其他轮数的预测正确数
int theta_i = 1, prefect_theta = it->first, max_num = theta[0];
for (auto jt = diff.begin(); jt != diff.end(); ++jt) {
theta[theta_i] = theta[theta_i - 1] + jt->second;
auto next_jt = next(jt); // 使用 next() 获取下一个迭代器
if (theta[theta_i] >= max_num) {
prefect_theta = next_jt->first;
max_num = theta[theta_i];
}
theta_i++;
}
cout << prefect_theta;
return 0;
}
369

被折叠的 条评论
为什么被折叠?



