[Advanced] (2016-08-22) 广告

在一个大厅内播放广告,广告开始播放时间是可选的
播放三段广告;
每段广告有时间长度li,每段广告有各自价值Pi;
广告需要让观众观看才有价值,第j个观众在大厅的停留时间是(Sj,Ej),如果第i个广告的播放时间落在第j个观众的停留时间内,则广告获得Pi的价值;
给定广告时间长度值li,广告价值Pi,观众数目N,各个观众的停留时间(Sj, Ej)。求选择各个广告的播放点,使得广告播放获取的价值最大。并输出最大广告价值。

限制: 每个广告只能播放一次;广告播放时间不能重叠;广告播放时间从1开始,最大是50.
每个人只能获得一个广告的价值(三个里边当然选择最大的)


输入:
第一行输入测试案例个数
第二行第一个是人数,第2-4个输入三个广告持续的时间li 然后分别是三个广告的价值pi
后面几行分别是每个人到达时间和停留时间


5


7 1 2 3 1 2 3
2 2
6 4
3 3
7 2
1 1
2 1
1 10


4 3 2 1 6 4 3
1 5
1 3
2 4
2 2


3 1 2 3 7 6 4
10 1
11 2
13 3


5 2 2 1 2 5 4
2 4
4 6
9 1
14 10
30 15


50 31 4 1 734 134 546 
1 39
4 28
9 24
12 16
7 29
6 27
12 14
24 18
1 34
11 20
5 23
31 16
12 38
3 35
10 2
35 14
11 34
31 13
6 14
10 7
4 17
15 19
7 36
8 19
13 20
7 18
27 6
9 5
13 14
2 20
9 12
5 13
34 12
5 20
17 7
18 31
33 6
14 8
4 6
10 38
23 10
36 13
17 15
27 20
11 21
27 1
31 13
20 16
47 2
19 26
#1 12
#2 18
#3 17
#4 16
#5 17998
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int T, answer, N, L1, L2, L3, P1, P2, P3, persons[50][2];

void calc(int start1, int start2, int start3){
	int result = 0;
	for (int i = 0; i < N; i++){
		int pointsPerson = 0;
		if (persons[i][0] <= start1 && persons[i][1] >= start1 + L1){
			if (pointsPerson < P1){
				pointsPerson = P1;
			}
		}
		if (persons[i][0] <= start2 && persons[i][1] >= start2 + L2){
			if (pointsPerson < P2){
				pointsPerson = P2;
			}
		}
		if (persons[i][0] <= start3  && persons[i][1] >= start3 + L3){
			if (pointsPerson < P3){
				pointsPerson = P3;
			}
		}
		result += pointsPerson;
	}

	if (answer < result){
		answer = result;
	}
}

int main(int argc, char** argv) {
	freopen("sample_input.txt", "r", stdin);
	setbuf(stdout, NULL);

	scanf("%d", &T);
	for (int test_case = 1; test_case <= T; ++test_case){
		answer = 0;
		scanf("%d%d%d%d%d%d%d", &N, &L1, &L2, &L3, &P1, &P2, &P3);

		int duration;
		for (int i = 0; i < N; i++){
			scanf("%d %d", &persons[i][0], &duration);
			persons[i][1] = persons[i][0] + duration;
		}

		for (int start1 = 1; start1 <= 50; start1++){
			for (int start2 = 1; start2 <= 50; start2++){
				if (start2 < start1 + L1 && start2 + L2 > start1){
					continue;
				}
				for (int start3 = 1; start3 <= 50; start3++){
					if (start3 < start1 + L1 && start3 + L3 > start1){
						continue;
					}
					if (start3 < start2 + L2 && start3 + L3 > start2){
						continue;
					}
					calc(start1, start2, start3);
				}
			}
		}

		printf("#%d %d\n", test_case, answer);
	}
	return 0;
}
一种特殊情况的case:
当某一个广告时间和分值很大,正好和某个人的duration相同时,如:

3 10 1 1 10 1 1
1 10
2 3
7 2


这种情况下的最优解就是这个最大的广告要正好cover这个人,所以我们不能设置成,要求三段广告的起点都在有人在的时间段内,否则这种最优解情形就无法得到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值