首页 > 学院 > 开发设计 > 正文

网易编程题(合唱团)

2019-11-10 20:24:26
字体:
来源:转载
供稿:网友

网易编程题(合唱团)

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

输入描述: 每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。

输出描述: 输出一行表示最大的乘积。

输入例子: 3 7 4 7 2 50

输出例子: 49

#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){ long long temp_k = -1e17; vector< long long > students; long long n; cin >> n; long long sum = n; while (n--) { long long temp; cin >> temp; students.push_back(temp); } long long k, d; cin >> k >> d; struct min_max{ min_max() :min{ 0 }, max{ 0 }{}; long long min; long long max; }; //声明结构体,因为有正有负所以要保存最大值和最小值 //vector<vector< long long >> *res = new vector<vector< long long >>{ n, vector< long long >{d, 0} }; vector<vector<min_max>> *res = new vector<vector< min_max>>(sum, vector<min_max>(k, min_max())); for (long long i = 0; i <sum; ++i) { (*res)[i][0].max = (*res)[i][0].min = students[i]; } //以i结尾的至多包含k个数字的成绩的最大值和最小值; for (long long i = 1; i <sum; ++i) { for (long long j = 1; j <= i&&j < k; ++j) { long long temp_min = -1e17; long long temp_max = 1e17; for (long long w = 1; w<i + 1 && w <= d; ++w){ if (temp_min<max(students[i] * (*res)[i - w][j - 1].min, students[i] * (*res)[i - w][j - 1].max)) temp_min = max(students[i] * (*res)[i - w][j - 1].min, students[i] * (*res)[i - w][j - 1].max); if (temp_max>min(students[i] * (*res)[i - w][j - 1].min, students[i] * (*res)[i - w][j - 1].max)) temp_max = min(students[i] * (*res)[i - w][j - 1].min, students[i] * (*res)[i - w][j - 1].max); } (*res)[i][j].max = temp_min; (*res)[i][j].min = temp_max; } } for (auto c : (*res)) { if (c[k - 1].max>temp_k) temp_k = c[k - 1].max; } cout << temp_k << endl; delete res; return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表