【枚举 数学】P11045 [蓝桥杯 2024 省 Java B] 最优分组|普及+
本文涉及知识点
[蓝桥杯 2024 省 Java B] 最优分组
题目描述
小蓝开了一家宠物店,最近有一种 X 病毒在动物之间进行传染,小蓝为了以防万一打算购买测试剂对自己的宠物进行病毒感染测试。
为了减少使用的测试剂数目,小蓝想到了一个好方法:将 N N N 个宠物平均分为若干组,使得每组恰好有 K K K 只宠物,这样对同一组的宠物进行采样并混合后用一个试剂进行检测,如果测试结果为阴性则说明组内宠物都未感染 X 病毒;如果是阳性的话则需要对组内所有 K K K 只宠物单独检测,需要再消耗 K K K 支测试剂(当 K = 1 K=1 K=1 时,就没必要再次进行单独检测了,因为组内只有一只宠物,一次检测便能确认答案)。
现在我们已知小蓝的宠物被感染的概率为 p p p,请问 K K K 应该取值为多少,才能使得期望的测试剂的消耗数目最少?如果有多个答案,请输出最小的 K K K。
输入格式
第一行,一个整数 N N N。
第二行,一个浮点数 p p p。
输出格式
输出一行,一个整数 K K K 表示答案。
样例 #1
样例输入 #1
1000
0.05
样例输出 #1
5
提示
【评测用例规模与约定】
对于 30 % 30\% 30% 的评测用例: 1 ≤ N ≤ 10 1\leq N\leq 10 1≤N≤10。
对于 60 % 60\% 60% 的评测用例: 1 ≤ N ≤ 1000 1\leq N\leq 1000 1≤N≤1000。
对于 100 % 100\% 100% 的评测用例: 1 ≤ N ≤ 1 0 6 1\leq N\leq 10^6 1≤N≤106, 0 ≤ p ≤ 1 0\leq p\leq 1 0≤p≤1。
枚举
K是1时,直接返回N。
K只宠物一组,阳性的概率ps[k]= 1-( 1- p)K
一组宠物需要的试剂数:1+ps[k]*K。
枚举K ∈ \in ∈[1,N] N %K ==0
时间复杂度:O(n) ( 1- p)K 用递推。
代码
核心代码
#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>
#include<list>
#include <bitset>
using namespace std;
template<class T1, class T2>
std::istream& operator >> (std::istream& in, pair<T1, T2>& pr) {
in >> pr.first >> pr.second;
return in;
}
template<class T1, class T2, class T3 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3>& t) {
in >> get<0>(t) >> get<1>(t) >> get<2>(t) ;
return in;
}
template<class T1, class T2, class T3, class T4 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4>& t) {
in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
return in;
}
template<class T = int>
vector<T> Read() {
int n;
scanf("%d", &n);
vector<T> ret(n);
for(int i=0;i < n ;i++) {
cin >> ret[i];
}
return ret;
}
template<class T = int>
vector<T> Read(int n) {
vector<T> ret(n);
for (int i = 0; i < n; i++) {
cin >> ret[i];
}
return ret;
}
class Solution {
public:
int Ans(const int N, double p) {
vector<double> ps(N + 1, 1);
for (int i = 1; i <= N; i++) {
ps[i] = ps[i - 1] * (1 - p);
}
double need = N;
int ans = 1;
for (int i = 2; i <= N; i++) {
if (0 != N % i) { continue; }
double curNeed = (1 + (1 - ps[i]) * i) * (N / i);
if (curNeed < need) {
need = curNeed;
ans = i;
}
}
return ans;
}
};
int main() {
#ifdef _DEBUG
freopen("a.in", "r", stdin);
#endif // DEBUG
int N; double p;
cin >> N >> p;
#ifdef _DEBUG
//printf("K=%d", K);
//Out(b, "b=");
//Out(a, ",a=");
#endif // DEBUG
auto res = Solution().Ans(N, p);
cout << res << endl;
return 0;
}
单元测试
TEST_METHOD(TestMethod11)
{
auto res = Solution().Ans(1000,0.05);
AssertEx(5, res);
}
扩展阅读
| 我想对大家说的话 |
|---|
| 工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
| 学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
| 有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
| 闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
| 如果程序是一条龙,那算法就是他的是睛 |
| 失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。
更多推荐

所有评论(0)