题目大意:一门课程,有N个小节要教,教每一个小节需要ti的时间,一堂课有L长的时间,教这N个小节有两个限制。1.每个小节要在同一堂课上教完,不能分开到两堂课里 2.要按顺序教,不能超前,就是第i+1小节必须要在第1小节到第i小节都教完的情况小才能教。每堂课的剩余时间会影响到学生的满意度,如果剩余时间刚好为0的话,这堂课的不满意度就为0,如果 >=1 && <= 10不满意度就为-C,其他情况不满意度为(剩余时间-10) * (剩余时间-10),要求用最少堂课教完,在最少堂课教完的情况下,要求学生的不满意度达到最低
解题思路:本来想用三维数组的,但是题目的n有点大,用不了,如果用三维数组的话,就可以表示为dp[i][j][step] = min (dp[i][j][step],dp[i][k][step-1] + d[k][l]),dp[i][j][step]表示第i小节到第j小节用了step堂课教的不满意度的最小值,d[k][l]表示第k小节到第j小节在同一堂课上上完的不满意度,只要dp[1][n][step]不为INF了,那么就表示用最少堂课上完了所有的小节了,且那个值也是最低的了,但这行不通,三维的话会爆掉,毕竟n <= 1000,既然不能三维的话,就叉开成两个一维的,l[i]表示上到第i小节用了多少堂课,ds[i]表示上到第i小节的不满意度为多少,那么就可以得到转换式子了,if(l[i] + 1 < l[j] ) 那么 l[j] = l[i] + 1,ds[j] = ds[i] + d[i+1][]j,毕竟以课为少为优先的,if(l[i] + 1 == l[j] && ds[i] + ds[i+1][j] < ds[j]),则ds[j] = ds[i] + d[i+1][j]
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1100
#define INF 0x3f3f3f3f
int dp[maxn][maxn],t[maxn],l[maxn],ds[maxn];
int n, L, C;
void init() {

	scanf("%d%d",&L,&C);
	for(int i = 1; i <= n; i++)
		scanf("%d",&t[i]);

	for(int i = 1; i <= n; i++)
		for(int j = i; j <= n; j++)
			dp[i][j] = INF;

	int temp,di,tt;
	for(int i = 1; i <= n; i++)  {
		temp = 0;
		for(int j = i ; j <= n; j++) {
			temp += t[j];
			tt = L - temp;
			if(temp > L)
				break;
			if(tt == 0)
				dp[i][j] = 0;
			else if( tt >= 1 && tt <= 10)
				dp[i][j] = -C;
			else 
				dp[i][j] = (tt - 10) * (tt - 10);	
		}
	}

}

void solve() {
	memset(ds,0x3f,sizeof(ds));
	memset(l,0x3f,sizeof(l));
	for(int i = 1;i <= n; i++) 
		if(dp[1][i] != INF) {
			ds[i] = dp[1][i];
			l[i] = 1;	
		}
	for(int i = 1 ; i <= n; i++) 
			for(int j = i + 1; j <= n; j++) {
				if(dp[i+1][j] == INF)
					break;
				if(l[i] + 1 < l[j]) {
					l[j]  = l[i] + 1;
					ds[j] = dp[i+1][j] + ds[i];	
				}
				else if(l[i] + 1 == l[j] && dp[i+1][j] + ds[i] < ds[j]) 
					ds[j] = ds[i] + dp[i+1][j];
			}

	printf("Minimum number of lectures: %d\n",l[n]);
	printf("Total dissatisfaction index: %d\n",ds[n]);
}

int main() {
	int mark = 1;
	int bo = 1;
	while(scanf("%d",&n) != EOF && n) {
		if(bo)
			bo = 0;
		else
			printf("\n");
		printf("Case %d:\n",mark++);
		init();
		solve();
	}
	return 0;
}