2020-11-23【奖学金问题(动态规划)】

2020-11-23

奖学金问题(动态规划)

题目描述

小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。

输入描述:

第一行三个整数n,r,avg(n大于等于1小于等于1e5,r大于等于1小于等于1e9,avg大于等于1小于等于1e6),接下来n行,每行两个整数ai和bi,均小于等于1e6大于等于1

输出描述:

一行输出答案。

示例1:

输入

5 10 9<br />0 5<br />9 1<br />8 1<br />0 1<br />9 100<br />

输出

43

方法一:

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            int r = sc.nextInt();
            int avg = sc.nextInt();
            
            long time = 0;
            long total = 0;
            ArrayList<FuXi> list = new ArrayList();
            for(int i=0; i<n; i++){
                long ai = sc.nextLong();
                total += ai;
                list.add(new FuXi(ai, sc.nextLong()));
            }
            total = n * avg - total;
            if(total <= 0){
                System.out.println(0);
                continue;
            }
            Comparator<FuXi> c = new Comparator<FuXi>(){
                public int compare(FuXi f1, FuXi f2){
                    if(f1.bi <= f2.bi){
                        return -1;
                    }else{
                        return 1;
                    }
                }
            };
            Collections.sort(list, c);
        
            for(int i=0; i<list.size(); i++){
                FuXi f = list.get(i);
                if(total <= r - f.ai){
                    time += total * f.bi;
                    break;
                }else{
                    time += (r - f.ai) * f.bi;
                    total -= r - f.ai;
                }
            }
            System.out.println(time);
        }
    }
}
class FuXi{
    long ai;
    long bi;
    public FuXi(long ai, long bi){
        this.ai = ai;
        this.bi = bi;
    }
}

方法二:


import java.util.Scanner;
import java.util.Arrays;
class Score implements Comparable<Score>{
 
  private int score;
  private int time;
  
public int getScore() {
	return score;
}
 
public void setScore(int score) {
	this.score = score;
}
 
public int getTime() {
	return time;
}
 
public void setTime(int time) {
	this.time = time;
}
 
	@Override
	public int compareTo(Score o) {
		if(this.time>o.time) return 1;
		else if(this.time==o.time) return 0;
		else return -1;
	}
 
	public Score(int score, int time) {
		super();
		this.score = score;
		this.time = time;
	}
	
	
}
 
public class Main {
	public static void main(String[] args) {	
		Scanner sc=new Scanner(System.in);
		while(sc.hasNextInt()){
			int n=sc.nextInt();
			int r=sc.nextInt();
			int avg=sc.nextInt();
			int init=n*avg;//总的平均值
			long result=0;//所需时间,最后的结果可能超过了int数据,所以改为long
             Score[] score=new Score[n];
			for (int i = 0; i < n; i++) { 
		    	score[i]=new Score(sc.nextInt(), sc.nextInt());
		    	init-=score[i].getScore();
			}//数据初始化完毕
		    Arrays.sort(score);//排序完毕
		    for (int i = 0; i < n; i++) {
				if(init>0){
					  if(r-score[i].getScore()<init){
						  result+=(r-score[i].getScore())*score[i].getTime();
						   init-=(r-score[i].getScore());  
					  }else{
						  result+=init*score[i].getTime();
							init=0;//结束 
					  }	
				}else{
					break;
				}
			}
		    //先去学价值最好的课程,学满为止
		    System.out.println(result);	    
		}
	}
}

方法三:(结构挺清晰)

import java.util.*;

public class Main {
   public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {        //注意while处理多个case
            int n = in.nextInt();
            long r = in.nextLong();
            long avg = in.nextLong();
            long[][] arr = new long[n][2];
            long total = avg*n;        //需要的分数
            long score = 0;            //现在的分数
            for(int i = 0;i<n;i++){
                arr[i][0] = in.nextLong();    //平时成绩
                arr[i][1] = in.nextLong();    //时间
                score += arr[i][0];
            }
            sort(arr);
            long time = 0;
            int i = 0;
            while(score<total&&i<n){
                if(arr[i][0]<r){
                    //第i门课没有满分
                    time += arr[i][1];
                    score++;
                    arr[i][0] += 1;
                }else{
                    i++;
                }
            }
            System.out.println(time);
            
       }
       in.close();
    }
    //对时间进行排序
    public static void sort(long[][]a){
        
        for(int i = 0;i<a.length-1;i++){
			boolean flag = true;
            for(int j = 0;j<a.length-1-i;j++){
                if(a[j][1]>a[j+1][1]){
                    long temp = a[j][0];
                    long temp2 = a[j][1];
                    a[j][0] = a[j+1][0];
                    a[j+1][0] = temp;
                    a[j][1] = a[j+1][1];
                    a[j+1][1] = temp2;
                    flag = false;
                }
            }
            if(flag)
                return;
        }
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值