赛马网 编程

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值