[codeforces]Goodbye_2015

来源:互联网 发布:vb是什么 编辑:程序博客网 时间:2024/05/09 16:50

611E - New Year and Three Musketeers

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Do you know the story about the three musketeers? Anyway, you must help them now.

Richelimakieu is a cardinal in the city of Bearis. He found three brave warriors and called them the three musketeers. Athos has strength a, Borthos strength b, and Caramis has strength c.

The year 2015 is almost over and there are still n criminals to be defeated. The i-th criminal has strength ti. It’s hard to defeat strong criminals — maybe musketeers will have to fight together to achieve it.

Richelimakieu will coordinate musketeers’ actions. In each hour each musketeer can either do nothing or be assigned to one criminal. Two or three musketeers can be assigned to the same criminal and then their strengths are summed up. A criminal can be defeated in exactly one hour (also if two or three musketeers fight him). Richelimakieu can’t allow the situation where a criminal has strength bigger than the sum of strengths of musketeers fighting him — a criminal would win then!

In other words, there are three ways to defeat a criminal.

A musketeer of the strength x in one hour can defeat a criminal of the strength not greater than x. So, for example Athos in one hour can defeat criminal i only if ti ≤ a.
Two musketeers can fight together and in one hour defeat a criminal of the strength not greater than the sum of strengths of these two musketeers. So, for example Athos and Caramis in one hour can defeat criminal i only if ti ≤ a + c. Note that the third remaining musketeer can either do nothing or fight some other criminal.
Similarly, all three musketeers can fight together and in one hour defeat a criminal of the strength not greater than the sum of musketeers’ strengths, i.e. ti ≤ a + b + c.
Richelimakieu doesn’t want musketeers to fight during the New Year’s Eve. Thus, he must coordinate their actions in order to minimize the number of hours till all criminals will be defeated.

Find the minimum number of hours to defeat all criminals. If musketeers can’t defeat them all then print “-1” (without the quotes) instead.

Input
The first line of the input contains a single integer n (1 ≤ n ≤ 200 000) — the number of criminals.

The second line contains three integers a, b and c (1 ≤ a, b, c ≤ 108) — strengths of musketeers.

The third line contains n integers t1, t2, …, tn (1 ≤ ti ≤ 108) — strengths of criminals.

Output
Print one line with the answer.

If it’s impossible to defeat all criminals, print “-1” (without the quotes). Otherwise, print the minimum number of hours the three musketeers will spend on defeating all criminals.

Sample test(s)
input
5
10 20 30
1 1 1 1 50
output
2
input
5
10 20 30
1 1 1 1 51
output
3
input
7
30 20 10
34 19 50 33 88 15 20
output
-1
input
6
10 5 10
10 9 5 25 20 5
output
3
Note
In the first sample Athos has strength 10, Borthos 20, and Caramis 30. They can defeat all criminals in two hours:

Borthos and Caramis should together fight a criminal with strength 50. In the same hour Athos can fight one of four criminals with strength 1.
There are three criminals left, each with strength 1. Each musketeer can fight one criminal in the second hour.
In the second sample all three musketeers must together fight a criminal with strength 51. It takes one hour. In the second hour they can fight separately, each with one criminal. In the third hour one criminal is left and any of musketeers can fight him.
题目大意:给定三个枪手的力量值,并给定n个敌人的力量值,每个枪手击倒一个敌人需要1个小时,若敌人的力量值需要两个枪手的力量值相加才能打倒则两个枪手需要合作打败敌人,同样花费一个小时,同样三个枪手的力量值相加才能击倒敌人,则同样花费一个小时,若其中有敌人的力量值大于三个枪手的力量值相加则输出-1,否则输出需耗费的最少时间
解题思路:用贪心的算法进行求解。
a、b、c、a+b、 a+c、 b+c、 a+b+c 从小到大排列存储在数组s中
分别计算处在7个段之间的敌人个数z[7]
1、sum += 小于a+b+c大于b+c的敌人个数
2、sum += 小于b+c大于a+c的敌人个数, 并相应的将小于a对应的z[0]减掉
3、sum += 小于a+c大于s[3]的敌人个数, 并相应的将小于b对应的z[1]减掉,z[1]减成0之后减z[0].
4、判断a+b>c,
若是的话,则sum += 小于a+b大于s[2]的敌人个数, 并相应的将小于c对应的z[2]减掉,z[2]减成0之后减z[1],z[1]减成0之后减z[0].进入步骤5
5、现留下的都是比c小的敌人,接下来判断采用a,b, c还是ab,c策略
当比b小的敌人存在时,才用a,b,c的策略要比ab,c的策略好
当不存在时则采用ab,c策略
用x记录比b小的敌人个数,用y记录比b大,比c小的敌人个数
当y>(x+1)/2 sum += (x+1)/2 + max((y - (x+1)/2 + 1)/2, z[3]-(x+1)/2);
max((y - (x+1)/2 + 1)/2, z[3]-(x+1)/2)有可能出现比ab大比c小的个数 z[3] 比ab小的个数z[2]要多(根据贪心策略 其耗费的最少时间为y - (x+1)/2 + 1)/2和z[3]-(x+1)/2两个值的最大值)
否则 sum += max((x+y+2)/3, (z[1]+y+1)/2);
max((x+y+2)/3, (z[1]+y+1)/2);有可能出现比a大的个数 z[1] + y比a小的个数z[0]要多(根据贪心策略 其耗费的最少时间为(x+y+2)/3和(z[1]+y+1)/2两个值的最大值)

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int a, b, c, n, t, flag = 0;int z[7];int s[7];int main() {    scanf("%d", &n);    scanf("%d%d%d", &a, &b, &c);    s[0] = a;    s[1] = b;    s[2] = c;    sort(s, s+3);    a = s[0];    b = s[1];    c = s[2];    s[3] = a+b;    s[4] = a+c;    s[5] = b+c;    s[6] = a+b+c;    sort(s, s+7);    memset(z, 0, sizeof(z));    for (int i = 0; i < n; i++) {        scanf("%d", &t);        for (int j = 0; j < 7; j++) {            if (t <= s[j]) {                z[j]++;                break;            }        }        if (t > s[6])            flag = 1;    }    if (flag) {        printf("-1\n");        return 0;    }    int ans = z[6], extra, extraa;    ans += z[5];    z[0] -= min(z[5], z[0]);    ans += z[4];    extra = z[4] - z[1];    z[1] -= z[4];    if (z[1] < 0) {        z[1] = 0;        extra = min(z[0], extra);        z[0] -= extra;    }    if (a+b > c) {        ans += z[3];        extra = z[3] - z[2];        extraa = extra-z[1];        z[2] -= min(z[2], z[3]);        if (extra > 0) {            z[1] -= min(extra, z[1]);        }        if (extraa > 0) {            z[0] -= min(extraa, z[0]);        }        z[3] = 0;    }    int x = z[0] + z[1];    int y = z[2] + z[3];    int a = max(z[1], (x+1)/2);    if (y > a)        ans += a + max((y - a + 1)/2, z[3]-a);    else        ans += max((x+y+2)/3, (z[1]+y+1)/2);    printf("%d\n", ans);    return 0;}
0 0
原创粉丝点击