/*問題描述:有n門課(編號為0~n-1),每門課都有考試。為了拿到獎學金,必須滿足所有課程平均成績至少為avg。每門課由平時成績和考試成績相加得到,滿足為r。現知道每門課平均成績ai(0<=i<=n-1),若想讓這門課多考一分,需要花bi的時間復習。同時,也可能出現復習再多也不會超過滿分的分數。為了拿到獎學金,請問至少需要花多少時間??
輸入描述:每個測試用例第一行為整數n(1<=n<=200),表示課程數,接下來n行,每行兩個整數,分別表示一門課的平均成績ai和bi,最后一行輸入滿分r和希望到達的平均成績avg,以輸入n==0結束
4
80 5
70 2
90 3
60 1
100 92.5
0
樣例輸出:
100
分析:既然選擇用貪心,那么就要制定貪心准則。既然給定了avg平均成績和n,那么我們不難得出拿到獎學金的總分為n*avg,同時每門課的平均成績也已給出,那么二者之差就是我們需要復習之后提高的分數了。而且這個分數,要用最少的時間來獲得。
所以要對bi進行排序。
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cmath> 5 #include<vector> 6 #include<stack> 7 #include<map> 8 #include<set> 9 #include<list> 10 #include<queue> 11 #include<string> 12 #include<algorithm> 13 #include<iomanip> 14 using namespace std; 15 #define MAX 201 16 int n; 17 struct score 18 { 19 /* data */ 20 int ai; 21 int bi; 22 bool operator < (const score & s)const 23 { 24 return bi < s.bi;//復習時間遞增排序 25 } 26 }; 27 28 score A[MAX]; 29 int r; 30 double avg; 31 int effort = 0; 32 33 void Solve() 34 { 35 int Sums = (int) n * avg;//需要達到的總分 36 int cursum = 0; 37 for(int i = 0 ; i< n; i ++)//現有課程的總分 38 { 39 cursum += A[i].ai; 40 } 41 sort(A,A + n); 42 for(int j = 0; j< n;j++)//貪心選擇 43 { 44 if(cursum >= Sums)//分數達到,結束選擇 45 { 46 break; 47 } 48 49 int cur = cursum; 50 cursum += min(Sums - cursum ,r - A[j].ai); 51 effort += A[j].bi * min(Sums-cur,r - A[j].ai); 52 } 53 } 54 int main() 55 { 56 while(cin>>n && n != 0 ) 57 { 58 for(int i = 0;i < n; i++) 59 { 60 cin>>A[i].ai>>A[i].bi; 61 } 62 cin>>r>>avg; 63 Solve(); 64 cout<<effort<<endl; 65 } 66 return 0; 67 }
for(int j = 0; j< n;j++)//貪心選擇
43 {
44 if(cursum >= Sums)//分數達到,結束選擇
45 { 46 break; 47 } 48 49 int cur = cursum; 50 cursum += min(Sums - cursum ,r - A[j].ai); 51 effort += A[j].bi * min(Sums-cur,r - A[j].ai); 52 }
針對這一段,簡單說一下,每門課已經按照單位復習時間遞增排了序,50行是為了找出 (需要達到的總分與目前總分的差,每門課的滿分r與當前平均成績ai的差)較小的那個,因為從單位復習時間最少的開始復習(同樣是總分加一分,當然是時間越少越好)。Sums-curcum==70,100-60=40,,所以花費時間為effort+= 1 * 40。即把60的成績復習到滿分,花費40分鍾,此時目前總分為340,還需30分,繼續循環單位復習時間第二小的那個,是70 ,2。Sums-cumin==30,100-70 ==30 ,所以這個復習到滿分剛好達到條件。此時(effort += 2 *(30)) == 100.所以最終至少需要花費100單位時間去復習。如果Sums-cursum < r-A[j].ai ,那就意味着當前課程不需要到滿分就能拿獎學金了,最后加上需要的時間就行了