首页 > ACM题库 > HDU-杭电 > Hdu 1476 Scheduling Lectures-记忆化搜索[解题报告] C++
2013
12-11

Hdu 1476 Scheduling Lectures-记忆化搜索[解题报告] C++

Scheduling Lectures

问题描述 :

You are teaching a course and must cover n (1 <= n <= 1000) topics. The length of each lecture is L (1 <= L <= 500) minutes. The topics require t1, t2, …, tn (1 <= ti <= 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 <= 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:

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.

This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

输入:

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 t1, t2, …, tn.

输出:

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.

样例输入:

6
30 15
10
10
10
10
10
10
10
120 10
80
80
10
50
30
20
40
30
120
100
0

样例输出:

Case 1:

Minimum number of lectures: 2
Total dissatisfaction index: 0

Case 2:

Minimum number of lectures: 6
Total dissatisfaction index: 2700


题意:给n节课时间,然后有一个一课时时间ti,和一个常数c,课必须连续着上不能换顺序,要求出最少需要的课时,和在该课时下学生不满意度最小值。
思路:前一步利用贪心,可以算出最少课时,就是尽量让多的课挤到一起上,然后在用记忆化搜索,求出该课时下最小满意度
代码:

#include <stdio.h>
#include <string.h>
const int N = 1005;
const int INF = 1 << 30;
int min(int a, int b) {return a < b ? a : b;}
int n, ti, c, count, t[N], dp[N][N], vis[N][N], i, j, num; 

int get(int x) {
	if (x == 0) return 0;
	else if (x <= 10) return -c;
	else return (x - 10) * (x - 10);
}

int solve(int x, int y) {
	if (vis[x][y]) return dp[x][y];
	int &ans = dp[x][y];
	if (x == 0) return y ? INF : 0;
	else {
		ans = INF;
		int sum = 0;
		for (int i = y; i > 0; i --) {
			sum += t[i];
			if (sum > ti) break;
			int now = solve(x - 1, i - 1);
			if (now != INF)
				ans = min(now + get(ti - sum), ans);
		}
		vis[x][y] = 1;
		return ans;
	}
}

int main() {
	int tt = 0;
	while (~scanf("%d", &n) && n) {
		num = 0;
		int sum = 1;
		memset(vis, 0, sizeof(vis));
		scanf("%d%d", &ti, &c);
		for (i = 1; i <= n; i ++) {
			scanf("%d", &t[i]);
			num += t[i];
			if (num > ti) {
				num = t[i];
				sum ++;
			}
		}
		if (tt) printf("\n");
		printf("Case %d:\n", ++ tt);
		printf("Minimum number of lectures: %d\n", sum);
		printf("Total dissatisfaction index: %d\n", solve(sum, n));
	}
	return 0;
}