考试。
一共有n道题,对于第i道题,有pi概率做对,获得ai分值,另外概率做错,则0分。总分为每道题分数之和。突击复习可以多复习m道题,复习之后正确率百分之百,求最佳复习的期望总分最大值。
输入:正整数n,m为总题数和最多复习题数;
第二行n个整数,p1~pn,做对题的概率,用百分表示
第三行n个整数,每个题目的分数a1~an
输出:一个小数点后两位数的小数。表示期望最大的总分。
思路:多复习的m题的分值*做错的概率,越大越好,将做错的概率乘以分值,即(1-pi)*ai,对其进行降序排序,然后选择前m道题。就可以得到复习之后,多得到的分数。则总分值就是不复习的分数+多复习m题的分数。
#include <cstdlib>
#include<iostream>
#include <utility>
#include <vector>
#include <deque>
#include<algorithm>
using namespace std;
bool great(double a,double b){
return a>b;
}
int main(){
int n,k;
cin>>n>>k;
int pint[n],score[n];
double p[n];
for(int i=0;i<n;i++){
cin>>pint[i];
p[i]=(double)pint[i]/100;
}
for(int i=0;i<n;i++){
cin>>score[i];
}
double noread;
double allscore=0;
deque<double> addscore;
for(int i=0;i<n;i++){
addscore.push_back((1-p[i])*score[i]);
noread+=p[i]*score[i];
}
sort(addscore.begin(),addscore.end(),great);
addscore.resize(k);//取前k个
for(int i=0;i<k;i++){
allscore=allscore+addscore[i];
}
cout<<allscore+noread<<endl;
return 0;
}
看起来没有问题,但是提交的时候正确率却很低,是因为粗心没有注意到题目的输出要求,要小数点后两位。。。。。写这么多代码就因为小数点后两位然后出错,太亏了!
这里附上正确输出的代码......
printf("%0.2f",allscore+noread);
我认为比较绝的是用到了resize
addscore.resize(k);
写代码的时候突然想到了看视频课的时候,说resize长度要是比数组原始长度小,就相当于截取数组长度的一部分数据,灵光一现。。。也可能是自己学识浅薄,不知道真正取数组前几位数据用什么。
还有为什么要用deque不用vector,其实两个都可以,我本来的思路是要进行头插的,后来就没有修改,deque可以头插头删,包含的功能比vector多一点,但是内部结构不同,内存扩展方式也不同。