秋招 - 算法

174 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情 >>

一、题目描述

要进行期末考试,一共有n道试题,对于第i道试题,有Pi的概率(为方便计算概率均乘以100)做对获得ai分,有(1-Pi)的概率做错获得0分。考试总分为每道题获得分数值之和。但如果考前进行复习则可以得到相应题的满分,并且由于精力有限最多复习m道题,若采取最优的复习策略,则能获得的期望总分最大是多少?
示例:

输入:n=2, m=1, 
     P = [89, 38], A = [445, 754]
输出:1150.05
解释:
如果都不复习,总分的期望为:89% * 445 + 38% * 754 = 682.57
如果复习第一道题,总分的期望为:100% * 445 + 38% * 754 = 731.52
如果复习第一道题,总分的期望为:89% * 445 + 100% * 754 = 1150.05
所以复习第二道题这样能获得最大期望总分。

二、解题思路

本题要求计算出最大期望总分。首先我们可以根据所给的概率和每道题目的分值计算出每道题目在不复习的情况下可以得到的期望分数,并用每道题目的总分分别减去相应的不复习的情况下可以得到的期望分数,将得到的差保存到数组中,并由大到小排列。选择前m大的数对应的题目进行复习即可达到最大期望分数。可以将差值与对应的题号组成一个内部类,并实现compare方法,从而实现按差值进行排序。

三、代码

public class App{
    class qst{
        int qs;
        int q;

        qst (int qs, int q){
            this.qs = qs;
            this.q = q;
        }
    }

    public double t3(int[] q, int[] s, int n, int m){
        double res = 0;
        List<qst> l = new ArrayList<>();
        for (int i=0; i<q.length; i++){
            l.add(new qst(s[i]*100 - q[i] * s[i], i));
        }
        Collections.sort(l, new Comparator<qst>() {
            @Override
            public int compare(qst o1, qst o2) {
                return o2.qs - o1.qs;
            }
        });
        for (int i=0; i<l.size(); i++){
            System.out.println(l.get(i).qs);
        }
        int i=0;
        for (i=0; i<m; i++){
            qst r = l.get(i);
            System.out.println(r.q);
            res += s[r.q];
            System.out.println(res);
        }
        for (;i<l.size(); i++){
            qst r = l.get(i);
            res += (double) (q[r.q] * s[r.q])/100.0;
        }
        return res;
    }
}

四、总结

本题通过构造内部类,实现了差值和题号的绑定,从而可以轻易的计算出最终的最大期望分数。