在一个大厅内播放广告,广告开始播放时间是可选的
播放三段广告;
每段广告有时间长度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这个人,所以我们不能设置成,要求三段广告的起点都在有人在的时间段内,否则这种最优解情形就无法得到