1、拍卖(京东2017实习生招聘真题) 1
公司最近新研发了一种产品,共生产了n件。有m个客户想购买此产品,第i个客户出价Vi元。为了确保公平,
公司决定要以一个固定的价格出售产品。每一个出价不低于要价的客户将会得到产品,余下的将会被拒绝购买。
请你找出能让公司利润最大化的售价。
输入
输入第一行二个整数n(1<=n<=1000),m(1<=m<=1000),分别表示产品数和客户数。 接下来第二行m个整数Vi(1<=Vi<=1000000),分别表示第i个客户的出价。
|
样例输入
5 4 2 8 10 7
|
输出
输出一行一个整数,代表能够让公司利润最大化的售价。
|
样例输出
7
|
时间限制C/C++语言:1000MS其它语言:3000MS
|
内存限制C/C++语言:65536KB其它语言:589824K
|
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
vector<int> res;
for(int i=0;i<m;i++)
{
int temp;
cin>>temp;
res.push_back(temp);
}
sort(res.begin(),res.end(),greater<int>());
int sum=numeric_limits<int>::min();
int r=res[0];
for(int i=0;i<m;i++)
{
int tempsum=res[i]*min(i+1,n);
if(sum<tempsum)
{
sum=tempsum;
r=res[i];
}
}
cout<<r<<endl;
}
2 通过考试(京东2017实习生真题) 2
题目描述小明同学要参加一场考试,考试一共有n道题目,小明必须做对至少60%的题目才能通过考试。考试结束后,
小明估算出每题做对的概率,p1,p2,...,pn。你能帮他算出他通过考试的概率吗?
输入
输入第一行一个数n(1<=n<=100),表示题目的个数。第二行n个整数,p1,p2,...,pn。表示小明有pi%的概率做对第i题。(0<=pi<=100)
|
样例输入
4 50 50 50 50
|
输出
小明通过考试的概率,最后结果四舍五入,保留小数点后五位。
|
样例输出
0.31250
|
时间限制C/C++语言:1000MS其它语言:3000MS
|
内存限制C/C++语言:65536KB其它语言:589824KB
|
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
int main() {
int N;
std::cin >> N;
std::vector<int> Parr(N+1);
Parr[0] = 0;
for(int i=1; i<=N; i++){
std::cin >> Parr[i];
}
// 状态:dp[i][j]代表共有i个题目,通过j个题目的概率
// 方程:dp[i][j] = P[j] * dp[i-1][j-1] + (1-P[j]) * dp[i-1][j]
// 即i个题目通过j个题目的概率,可以表示为,如果第j个题目通过了,那么前i-1个题目中我通过了j-1个,所以这部分概率为 P[j] * dp[i-1][j-1]
// 如果第j个题目没有通过,那么前i-1个题目中我通过了j个,所以这部分概率为(1 - P[j]) * dp[i-1][j]
// 初始化: dp[0][0] = 1, dp[0][1] = 0;
std::vector<std::vector<double>> dp(N+1, std::vector<double>(N+1, 0));
dp[0][0] = 1;//这一句很重要
dp[0][1] = 0;
for(int i=1; i<=N; i++){
dp[i][0] = (1 - double(Parr[i]) / 100) * dp[i-1][0];
for(int j=1; j<=i; j++){
dp[i][j] = double(Parr[i]) / 100 * dp[i-1][j-1] + (1 - double(Parr[i]) / 100) * dp[i-1][j];
}
}
//最少要通过 min 个题目
int min = ceil(N * 0.6);
double ans = 0.0;
//最后的结果即 dp[N][min] + dp[N][min + 1] + ... + dp[N][N]
// 即 N个题目中通过min个, 通过min+1个 。。。 通过N个的概率相加
for(int i=min; i<=N; i++){
ans += dp[N][i];
}
printf("%.5f", ans);
}
//当然这道题目还可以优化,即使用滚动数组代替二维数组,此时空间复杂度由O(n^2)变为O(n)
//代码如下
/*
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
int main() {
int N;
std::cin >> N;
std::vector<int> Parr(N+1);
Parr[0] = 0;
for(int i=1; i<=N; i++){
std::cin >> Parr[i];
}
std::vector<double> dp(N+1, 0);
dp[0] = 1;
for(int i=1; i<=N; i++){
dp[0] = (1 - double(Parr[i]) / 100) * dp[0];
for(int j=i; j>=1; j--){
dp[j] = double(Parr[i]) / 100 * dp[j-1] + (1 - double(Parr[i]) / 100) * dp[j];
}
}
int min = ceil(N * 0.6);
double ans = 0.0;
for(int i=min; i<=N; i++){
ans += dp[i];
}
printf("%.5f", ans);
} */
2 分堆A(京东2017实习生真题) 2
题目描述小明得到了n个石头,他想把这些石头分成若干堆,每堆至少有一个石头。他把这些石堆排在一条直线上,他希望任意相邻两堆的石头数都不一样。小明最后的得分为石头数大于等于k的石堆数,问他最多能得多少分。
严格地,小明把n个石头分成了m堆,每堆个数依次为a1,a2.....,am。要求满足:
1、ai≥1(1≤i≤m)2、ai≠ai+1(1≤i<m)3、a1+a2+...+am=n小明想知道中大于等于的数最多能有多少个?
输入
输入两个数n, k。
|
样例输入
5 1
|
输出
输出最大的得分
|
样例输出
3
|
时间限制C/C++语言:1000MS其它语言:3000MS
|
内存限制C/C++语言:65536KB其它语言:589824
|