UVa 607 Scheduling Lectures(简单DP)

题意:

有n个主题。每堂课的时间是L。每个主题各要求t1,t2,...tn(1<=ti<=L)。对于每个主题,你要决定要哪堂课教。并且有如下的规则:
1.每个主题必须完整地包含在一堂课里。不能分成两部分教。
2.主题之间的顺序不能调换,即主题i必须在主题i+1之前教。
同时,如果在每堂课的最后如果能留有10分钟以内的时候,那么学生的不满意程序是最小的。不满意程度的计算如下所示:
D=0(如果剩下的时间是0)。
D=-c(如果剩下的时间在10分钟以内)。
D=(t-10)^2(剩下的情况)

思路:

dp[i, j]表示前i节课,覆盖j个知识点的最小不满意度。

#include <cstdio> #include <cstdlib> #include <cstring> #include <climits> #include <algorithm>

using namespace std; const int MAXN = 1010; int dp[MAXN][MAXN]; int a[MAXN], sum[MAXN]; int L, C; int getvalue(int v) { int t = L - v; if (t == 0) return 0; else if (0 < t && t <= 10) return -C; else if (t > 10) return (t - 10) * (t - 10); } int main() { int n; int cases = 0; while (scanf("%d", &n) && n) { scanf("%d %d", &L, &C); sum[0] = 0; for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i]; for (int i = 0; i <= n; ++i) { dp[i][0] = 0; for (int j = 1; j <= n; ++j) dp[i][j] = INT_MAX; } for (int i = 1; dp[i-1][n] == INT_MAX; ++i) for (int j = i; j <= n && sum[j] <= i * L; ++j) for (int k = j; k >= i - 1; --k) if (sum[j] - sum[k] <= L && dp[i-1][k] != INT_MAX) dp[i][j] = min(dp[i][j], dp[i-1][k] + getvalue(sum[j] - sum[k])); else if (sum[j] - sum[k] > L) break; int i; for (i = 1; i <= n; ++i) if (dp[i][n] != INT_MAX) break; if (cases) printf("\n"); printf("Case %d:\n", ++cases); printf("Minimum number of lectures: %d\n", i); printf("Total dissatisfaction index: %d\n", dp[i][n]); } return 0; }

 

 

你可能感兴趣的:(uva)