网易在线编程题 奖学金问题

小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



输出描述:
一行输出答案。

 

输入例子:
5 10 9
0 5
9 1
8 1
0 1
9 100

 

输出例子:
43


我是按照多重背包问题来求解的,因为没有任何优化,所以运行超时。先记录下来,如果以后有时间再进行优化。
 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class ReviewedTime{    
 5     
 6     public static void main(String[] args)throws Exception{
 7         Scanner scanner=new Scanner(System.in);
 8 
 9         while(scanner.hasNext()){
10             int n = scanner.nextInt();
11             int r = scanner.nextInt();  // 每门课的满分
12             int avg = scanner.nextInt();
13             int[] a=new int[n]; // 每门课的平时成绩
14             int[] b=new int[n]; // 每门得一分所需要的复习时间
15             int[] c=new int[n]; // 每门课最多可以提高的分数 
16             int totalScoresNeeded=0; //为了达到目标需要提高的总分数
17             
18             for(int i=0;i<n;i++){
19                 a[i]=scanner.nextInt();
20                 b[i]=scanner.nextInt();
21                 c[i]=r-a[i];
22                 
23                 totalScoresNeeded+=avg-a[i];
24             }
25             
26             int time=new ReviewedTime().getLeastReviewedTime(c,b,totalScoresNeeded);
27             System.out.println(time);
28         }
29         
30         
31     }
32     
33     /**
34      * dp[i][j] 表示前i门课得到分数j所需要的最少时间
35      * dp[i][j]=min{dp[i-1][j-k]+k*b[i] | 0<=k<=c[i]&&k<=j}
36      * @param c c[i]表示第i门课可以提高的分数
37      * @param b b[i]表示每提高第i门课一分需要花费的时间
38      * @param totalScoresNeeded
39      * @return
40      */
41     public int getLeastReviewedTime(int[] c, int[] b,int totalScoresNeeded){
42         if(c.length==0 || c==null || totalScoresNeeded<0)
43             return -1;
44         int[][] dp=new int[c.length][totalScoresNeeded+1];
45         int max=Integer.MAX_VALUE;
46         int n=c.length;
47         
48         for(int j=1;j<=totalScoresNeeded;j++){
49             dp[0][j]=max;   //表示花再多时间都没办法达标
50             if(j<=c[0]){
51                 dp[0][j]=j*b[0];
52             }
53         }
54 
55         for(int i=1;i<n;i++){
56             for(int j=1;j<=totalScoresNeeded;j++){
57                 dp[i][j]=dp[i-1][j];
58                 for(int k=1; k<=c[i]&&k<=j; k++){
59                     if(dp[i-1][j-k]!=max)
60                         dp[i][j]=Math.min(dp[i][j], dp[i-1][j-k]+k*b[i]);
61                 }
62             }
63         }
64         
65         return dp[n-1][totalScoresNeeded]!=max ? dp[n-1][totalScoresNeeded]:-1;
66     }
67 }
ReviewedTime

 

posted @ 2016-03-21 16:24  kylinxue  阅读(975)  评论(0编辑  收藏  举报