UVA 607 (dp记忆化搜索)

本文探讨了在教学过程中如何高效安排课程与讲座,确保覆盖所有必要主题的同时,通过减少讲座间的空闲时间来提高学生满意度。文章提出了基于贪心算法与记忆化搜索的方法,以最小化讲座数量并降低总不满意度指数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  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 

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

题意:给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;
}


### 关于记忆化搜索的练习题 在洛谷平台上有许多涉及记忆化搜索的经典题目,这些题目可以帮助学习者更好地理解动态规划与深度优先搜索相结合的方法。以下是几个推荐的记忆化搜索练习题及其背景介绍: #### 题目一:P4170 [CQOI2007] 涂色 此题属于经典的 DP 类型问题之一,主要考察如何通过记忆化的方式优化暴力枚举的过程[^1]。 该题的核心在于利用状态压缩技术存储已经处理过的子结构,并结合 DFS 的方式逐步扩展解空间。 #### 题目二:P1464 Function 这是一个典型的递归加记忆化的入门级题目[^2]。它强调了在搜索过程中记录中间结果的重要性,从而避免不必要的重复计算。具体实现上可以通过定义一个辅助数组 `f[x][y]` 来保存已访问的状态值。 #### 题目三:UVA - 1629 Cake Slicing 这篇文章提到的一道经典例题展示了记搜的优势所在[^3]。通过对不同切割方案的结果进行缓存操作,可以显著降低时间复杂度并提高效率。 #### 题目四:滑雪 (P1434) 作为一道非常受欢迎的记忆化搜索练习题,“滑雪”模拟了一个二维网格上的最长下降路径求解过程[^5]。给定一张地图表示各个位置的高度分布情况后,我们需要找到从任意起点出发能够达到的最大步数长度。 ```python from functools import lru_cache @lru_cache(None) def dfs(x, y): res = 1 directions = [(0,-1),(-1,0),(0,+1),(+1,0)] for dx, dy in directions: nx, ny = x + dx, y + dy if 0<=nx<R and 0<=ny<C and grid[nx][ny]<grid[x][y]: res = max(res, dfs(nx, ny)+1 ) return res R,C=map(int,input().split()) grid=[list(map(int,input().strip().split()))for _ in range(R)] ans=0 for i in range(R): for j in range(C): ans=max(ans ,dfs(i,j)) print(ans) ``` 上述代码片段实现了基于 Python 的解决方案,其中运用装饰器 @lru_cache 实现自动化的函数调用结果缓存功能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值