uva 607(dp)

题意:一个人要开讲座将n个专题,每场讲座l分钟,每个观众的耐心是c,然后给出n个专题需要讲的时间,问最少几场讲座能把专题讲完,观众的不满度的和是多少。

规则是这样,讲座的时间必须大于等于k个专题的时间和,剩下的时间t如果在十分钟内,观众不满度会降低c,大于10的观众的不满度会增加(t-10)^2,专题要按顺序讲解。

题解:需要两个dp数组迭代,num[i]表示i个专题最少开几场讲座,f[i]表示i个专题时观众的最小不满度和,在l - (sum[i] - sum[j - 1]) >= 0 的情况下,也就是专题j到专题i可以在一场讲座讲完的情况下,如果num[i] > num[j - 1] + 1,那么就更新num[i]的值,并且更新f[i]的值,如果两者相等说明专题j到专题i可以合并成1场,并更新此时的f[i]值。

#include <stdio.h>
#include <string.h>
const int N = 1005;
const int INF = 0x3f3f3f3f;
int n, l, c, tp;
int sum[N], f[N], num[N];

int get_di(int x) {
	if (x >= 1 && x <= 10)
		return -c;
	if (x > 10)
		return (x - 10) * (x - 10);
	return 0;
}

int min(int a, int b) {
	return a < b ? a : b;
}

int main() {
	int cas = 1;
	while (scanf("%d", &n) && n) {
		memset(sum, 0, sizeof(sum));
		scanf("%d%d", &l, &c);
		sum[0] = f[0] = num[0] = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%d", &tp);
			sum[i] = sum[i - 1] + tp;
		}
		for (int i = 1; i <= n; i++) {
			f[i] = num[i] = INF;
			for (int j = 1; j <= i; j++) {
				int t = l - (sum[i] - sum[j - 1]);
				if (t >= 0) {
					if (num[i] > num[j - 1] + 1) {
						num[i] = num[j - 1] + 1;	
						f[i] = f[j - 1] + get_di(t);
					}
					else if (num[i] == num[j - 1] + 1) {
						f[i] = min(f[i], f[j - 1] + get_di(t));
					}
				}
			}
		}
		if (cas != 1)
			printf("\n");
		printf("Case %d:\n", cas++);
		printf("Minimum number of lectures: %d\n", num[n]);
		printf("Total dissatisfaction index: %d\n", f[n]);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值