这个周末做了最佳阈值这道题,C++实现,时间使用156ms,空间使用4.117MB。
题目链接:
题目解析如下:
第二题一般需要用到快速排序、归并排序等复杂度为O(nlogn)
的算法,这种算法在考试的时候直接手写十分麻烦,而且容易出错,所以说我们一般采用Sort
函数。而Sort
函数通常可以用于数组、Vector等类中,但是题目每一个输入对象拥有两个子变量,一个是
θ
\theta
θ,另一个是
r
e
s
u
l
t
i
result_i
resulti,因此我们还是要对输入建立一个score
类,如果要用vector
储存这个类,建立一个列表的话,那么调用Sort
函数都时候还要重载运算符<
。而在解题过程中,用到了动态规划的思想,算法的遍历复杂度为O(n)
。本题考查的知识点如下:
C++:运算符重载,STL<vector>模板库,以及sort函数的正确使用。
算法:动态规划
动态规划的状态转移代码如下,result[i]+result2[i]
数组代表着以scoreset[i].state
为阈值的结果。当然,在提交的时候出现了很多坑。主要是动态规划的第一个循环错了好几次,因此在写状态转移方程的时候要尽量考虑到所有的情况,需要在心里多过几次。不然考试的时候容易寄。
for (i = 1; i < scoreset.size(); i++) {
result[i] = result[i - 1];//自下往上遍历,用于记录小于阈值的情况。
if (scoreset[i - 1].theta != scoreset[i].theta) { result[i] += (1 - scoreset[i - 1].state); result[i] += temp; temp = 0; }
//如果二者thetae值不相等,那么就把temp加上去,并且清空。1-result[i-1]就是如果state为0,那么就预测正确。反之预测错误。
else if (scoreset[i-1].state==0){temp++; }
//如果二者theta值相等,因为取该点为阈值,所以说这一点的state为0是不能算的,先计入temp中。
}
vector<int>result2(num); result2[num - 1] = (scoreset[num - 1].state);
for (i = scoreset.size() - 2; i >= 0; i--) {
//自上往下遍历,用于记录大于阈值的情况。
result2[i] = result2[i + 1] + (scoreset[i].state);
}
整体代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class score {
public:
bool operator<(const score& a) {
return (this->theta < a.theta) ? true : false;
//定义重载运算符
};
bool operator>(const score& a) {
return (this->theta > a.theta) ? true : false;
};//对于sort而言,只用定义<即可,这部分可以删去。
score(int a, int b) {
this->state = b;
this->theta = a;
};
int theta;
int state;
//输入的变量
};
int main(void) {
int num; cin >> num;
vector<score>scoreset(num);
int i, j; int state, theta; int maxtheta = 0;
for (i = 0; i < num; i++) {
cin >> theta >> state;
scoreset[i] = score(theta, state);
}//将输入的变量引入数据结构中。
sort(scoreset.begin(), scoreset.end());
//对所有学生的theta信息从小到大排序
vector<int>result(num); result[0] = 0; int temp = 0;
for (i = 1; i < scoreset.size(); i++) {
result[i] = result[i - 1];
if (scoreset[i - 1].theta != scoreset[i].theta) { result[i] += (1 - scoreset[i - 1].state); result[i] += temp; temp = 0; }
else if (scoreset[i-1].state==0){temp++; }
}
vector<int>result2(num); result2[num - 1] = (scoreset[num - 1].state);
for (i = scoreset.size() - 2; i >= 0; i--) {
result2[i] = result2[i + 1] + (scoreset[i].state);
}
int maxer = 0; int flager = scoreset[0].theta;
//for (i = 0; i < num; i++)cout << result[i] <<' ' << result2[i] << endl;
for (i = 0; i < scoreset.size(); i++) {
if ((result[i] + result2[i]) >= maxer) {
maxer = result[i] + result2[i];
flager = scoreset[i].theta;
}
}
cout<<flager;
return 0;
}
```C++