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
Miguel A. Revilla
1999-04-06
题目大意:
教授一门课程,每次讲座时长为L,共有n个知识点需要讲授,每个知识点需要花费 t[i] 的时间。要求一个知识点不能拆开到两次讲座中,且必须按顺序讲授。问怎样安排知识点,使得总的讲座数最少,同时让不满意度最低。不满意度有每次讲座提前结束的时间决定,服从题目中的DI函数。
解题思路:
对于总讲座数最少的问题,因为知识点必须按顺序讲授,很容易想到用贪心的方法,每次讲座尽可能填满,安排不下只能新开一次讲座。
对于不满意度最低的问题,用DP解决, dp[i][j]表示用i次讲座容纳前j个知识点的最低不满意度。
状态转移方程:dp[i][j] = min(dp[i][k] + DI(L-sum) ) ( sum = t[k+1] + t[k+2] + .. + t[j], sum <= L)
参考代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
int cCase, n, L, C, cnt, t[MAXN], dp[MAXN][MAXN];
void init() {
cnt = 1;
memset(dp, -1, sizeof(dp));
}
void input() {
scanf("%d%d", &L, &C);
for (int i = 0; i < n; i++) {
scanf("%d", &t[i]);
}
}
int calcDI(int t) {
if (t == 0) return 0;
if (t >= 1 && t <= 10) return -C;
return (t - 10) * (t - 10);
}
int DP(int x, int y) {
if (x == 0) return y == 0 ? 0 : INF;
if (dp[x][y] != -1) return dp[x][y];
int sum = 0, ret = INF;
for (int i = y-1; i >= 0; i--) {
sum += t[i];
if (sum > L) break;
int tmp = DP(x-1, i);
if (tmp != INF) {
ret = min(ret, tmp + calcDI(L-sum));
}
}
return dp[x][y] = ret;
}
void solve() {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += t[i];
if (sum > L) {
cnt++;
sum = t[i];
}
}
if (cCase > 0) printf("\n");
printf("Case %d:\n", ++cCase);
printf("Minimum number of lectures: %d\n", cnt);
printf("Total dissatisfaction index: %d\n", DP(cnt, n));
}
int main() {
while (~scanf("%d", &n) && n) {
init();
input();
solve();
}
return 0;
}