Scheduling Lectures - UVa 607 dp

来源:互联网 发布:java 事物的特征 编辑:程序博客网 时间:2024/05/16 06:29

Scheduling Lectures

You are teaching a course and must cover n ( $1 \le n \le 1000$) topics. The length of each lecture is L ($1 \le L \le 500$) minutes. The topics require $t_1, t_2, \dots, t_n$ ( $1 \le t_i \le L$) 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 $1 \le i < n$. 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: 

\begin{displaymath}DI = \cases{0 & if $t=0$, \cr-C & if $1 \le t \le 10$, \cr(t-10)^2 & otherwise}\end{displaymath}

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 $t_1, t_2, \dots, t_n$.

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 

630 1510101010101010120 1080801050302040301201000

Sample Output 

Case 1:Minimum number of lectures: 2Total dissatisfaction index: 0Case 2:Minimum number of lectures: 6Total dissatisfaction index: 2700

题意:在最少的上课次数的情况下,输出最小的学生不满意度。

思路:首先可以用贪心算出来最少需要上多少次课,然后记录l[i],r[i]数组记录第i天最少和最多应该讲到第几个知识点。然后dp[i][j]表示在第i天讲完第j个知识点的最少不满意度。

AC代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int l[1010],r[1010],ti[1010],st[1010],n,len,c,day,dp[1010][1010],INF=1000000000;int solve(int k){ int t=len-k;  if(t==0)   return 0;  if(t>=1 && t<=10)   return -c;  return (t-10)*(t-10);}int main(){ int t=0,i,j,k,p;  while(~scanf("%d",&n) && n)  { scanf("%d%d",&len,&c);    for(i=1;i<=n;i++)    { scanf("%d",&ti[i]);      st[i]=st[i-1]+ti[i];    }    day=0;k=0;    for(i=1;i<=n;i++)    { k+=ti[i];      if(k>len)      { i--;day++;k=0;        r[day]=i;      }    }    day++;r[day]=n;    memset(l,0,sizeof(l));    p=day;k=0;    for(i=n;i>=1;i--)    { k+=ti[i];      if(k>len)      { i++;k=0;        l[p]=i;p--;      }    }    for(i=1;i<day;i++)     l[i]=max(0,l[i+1]-1);    l[day]=n;    for(i=1;i<=day;i++)     for(j=l[i];j<=r[i];j++)      dp[i][j]=INF;    dp[0][0]=0;    for(i=0;i<day;i++)     for(j=l[i];j<=r[i];j++)      for(k=l[i+1];k<=r[i+1];k++)       if(j==0)       { if(st[k]<=len)          dp[i+1][k]=min(dp[i+1][k],dp[i][j]+solve(st[k]));       }       else if(j<=k && st[k]-st[j]<=len)        dp[i+1][k]=min(dp[i+1][k],dp[i][j]+solve(st[k]-st[j]));    if(t)     printf("\n");    printf("Case %d:\n",++t);    printf("Minimum number of lectures: %d\n",day);    printf("Total dissatisfaction index: %d\n",dp[day][n]);  }}



0 0
原创粉丝点击