2014-08-25 00:16:29
Scheduling Lectures |
You are teaching a course and must cover n ( ) topics. The length of each lecture is L ( ) minutes. The topics require ( ) minutes each. For each topic, you must decide in which lecture it should be covered. There are two scheduling restrictions:
-
1.
- Each topic must be covered in a single lecture. It cannot be divided into two lectures. This reduces discontinuity between lectures. 2.
- Topic i must be covered before topic i + 1 for all . Otherwise, students may not have the prerequisites to understand topic i + 1.
With the above restrictions, it is sometimes necessary to have free time at the end of a lecture. If the amount of free time is at most 10 minutes, the students will be happy to leave early. However, if the amount of free time is more, they would feel that their tuition fees are wasted. Therefore, we will model the dissatisfaction index (DI) of a lecture by the formula:
where C is a positive integer, and t is the amount of free time at the end of a lecture. The total dissatisfaction index is the sum of the DI for each lecture.
For this problem, you must find the minimum number of lectures that is needed to satisfy the above constraints. If there are multiple lecture schedules with the minimum number of lectures, also minimize the total dissatisfaction index.
Input
The input consists of a number of cases. The first line of each case contains the integer n, or 0 if there are no more cases. The next line contains the integers L and C. These are followed by n integers .
Output
For each case, print the case number, the minimum number of lectures used, and the total dissatisfaction index for the corresponding lecture schedule on three separate lines. Output a blank line between cases.
Sample Input
6 30 15 10 10 10 10 10 10 10 120 10 80 80 10 50 30 20 40 30 120 100 0
Sample Output
Case 1: Minimum number of lectures: 2 Total dissatisfaction index: 0 Case 2: Minimum number of lectures: 6 Total dissatisfaction index: 2700
思路:这个题目有两个要求,第一:要求课程总数最小;第二:在课程总数最小的前提下,使 dissatisfaction 最小。一开始,没什么思路,看了别人的题解后幡然顿悟:第一个要求可以用贪心法解决。第二个要求用DP来解,dp[i][j]表示前i个 topics 放在前j节课中讲的最小 dissatisfaction,再通过枚举第j节课中的 topics 数,就能记忆化搜索了(如果不用贪心求出最小课程数,就不知道记忆化搜索的起点,DP就无从下手了)
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 const int INF = 1 << 30; 8 9 int Case = 0; 10 int n,L,c; 11 int t[1005]; 12 int dp[1005][1005]; 13 int used[1005][1005]; 14 int cnt; 15 int deep; 16 17 int Cal(int x){ 18 if(x == 0) 19 return 0; 20 if(x >= 1 && x <= 10) 21 return -c; 22 else 23 return (x - 10) * (x - 10); 24 } 25 26 int Solve(int x,int y){ 27 if(used[x][y]) 28 return dp[x][y]; 29 if(y < 1) 30 return x ? INF : 0; 31 int tmin = INF; 32 int tvol = L; 33 int tem; 34 for(int i = x; i >= 1; --i){ 35 tvol -= t[i]; 36 if(tvol >= 0){ 37 tem = Solve(i - 1,y - 1); 38 if(tem != INF){ 39 tmin = min(tmin,tem + Cal(tvol)); 40 } 41 } 42 else{ 43 break; 44 } 45 } 46 used[x][y] = 1; 47 return dp[x][y] = tmin; 48 } 49 50 int main(){ 51 //freopen("in.txt","r",stdin); 52 while(scanf("%d",&n) == 1 && n){ 53 scanf("%d%d",&L,&c); 54 int tsum = 0,deep = 1; 55 for(int i = 1; i <= n; ++i){ 56 scanf("%d",&t[i]); 57 tsum += t[i]; 58 if(tsum > L){ 59 tsum = t[i]; 60 ++deep; 61 } 62 } 63 if(Case) 64 printf("\n"); 65 printf("Case %d:\n",++Case); 66 printf("Minimum number of lectures: %d\n",deep); 67 memset(used,0,sizeof(used)); 68 printf("Total dissatisfaction index: %d\n",Solve(n,deep)); 69 } 70 return 0; 71 }