acdream 1073(贪心)

题意:

战机分为升级和进阶两种。

升级:提升战机的等级,但战机品质不变。

进阶:可将战机提升一个星级(白二星->绿三星->蓝四星->紫五星)。

为了简化问题,规定战机进阶规则如下:

白色二星:

起始等级Lv1级,满级Lv25级。

Lv1升级到Lv25,总共需要A经验。

进阶到绿色三星条件:满级Lv25后,方可进阶。

绿色三星:

起始等级Lv25级,满级Lv30级。

Lv25升级到Lv30,总共需要B经验。

进阶到蓝色四星条件:满级Lv30后,方可进阶。

蓝色四星:

起始等级Lv30级,满级Lv60级。

Lv30升级到Lv60,总共需要C经验。

进阶到紫色五星条件:满级Lv60后,方可进阶。

紫色五星:

起始等级Lv60级,满级Lv75级。

Lv60升级到Lv75,总共需要D经验。

满级LV75后,最强战机诞生!

现在风风手上有1架Lv1级的白二星,和N个经验球(可以升级战机的球球~~~),每个经验球都有一定的经验值。

每次风风都只能使用一个经验球给战机升级,并且每个经验球只能用一次后就会消失。

另外,风风有个习惯。就是每次都会优先选择能将战机升级到相应星级对应的满等级的最小的经验球。若剩下的经验球中最大的经验球也不能将现在的战机升到满级,那么风风就会选择这些剩下的经验球里面经验值最大的那个经验球对战机进行升级了。

如果按照风风的方式对战机进行升级进阶,风风能否成功将自己的战机升级到满级LV75的紫色战机呢?

如果能,请告诉风风,他最后剩下的未被使用的经验球的经验总和是多少?

注意:如果使用某个经验球使战机升级到满级了,那么多出的经验是不会累积的,这时候你需要对战机进阶到下一个品质,提升满级的等级。才可以继续升级。

例如:

现在有一架绿色三星Lv29的战机,还需要80的经验可以升级到满级Lv30。如果你使用了经验为9999的经验球。只能将战机升级到满级Lv30,而不会升级到Lv31级以上,经验值不会累积。因为在使用经验球的同时,无法进行进阶。因为进阶需要满级后,才可以进阶。

另外,值得一提的是:如果是一架绿色三星Lv9的战机,还需要10的经验升级到Lv10,而Lv10到Lv11需要15点经验,Lv11到Lv12需要22点经验。那么你使用经验值为30的经验球,可以将战机直接升级到Lv11,并且还需要17点经验升级到Lv12。(也就是说还未达到满级的战机,使用经验球可以跨级升级,而满级后,需要进阶到下一个品质,才可以继续升级)。

Input

输入包含多组数据,对于每组数据:

第一行:N(表示有N个经验球,1<=N<=1000)

第二行:A B C D(分别表示各个星级从起始级升到相应星级的满级所需的总经验,详情见上述题目描述,1<=A,B,C,D<=99999)

第三行:N个经验球的经验值EXP[i] (1<=EXP[i]<=99999)

Output

如果能进阶到满级Lv75紫色战机,输出“YES”,并输出最后剩下的未被使用的经验球的经验总和是多少。

如果不能,输出“NO”。

Sample Input

3

400 250 800 2000

99999 99999 99999

4

400 2000 5000 10000

9999 9999 9999 9999

4

400 2000 5000 10000

99999 99999 99999 99999

5

1000 2000 8000 10000

1000 2000 5000 10000 20000

Sample Output

NO

NO

YES 0

YES 5000

题解:直接按题意那样模拟,注意如果所有经验球都使它无法进阶,那么选最大经验球加上,然后再从小开始选,是否有能让他进阶的经验球。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1005;
int n, a[4], b[N], vis[N];

int main() {
    while (scanf("%d", &n) == 1) {
        for (int i = 0; i < 4; i++)
            scanf("%d", &a[i]);
        for (int i = 0; i < n; i++)
            scanf("%d", &b[i]);
        if (n < 4) {
            printf("NO\n");
            continue;
        }
        memset(vis, 0, sizeof(vis));
        sort(b, b + n);
        int i, j, cnt = 0;
        for (i = 0; i < 4; i++) {
            for (j = 0; j < n; j++)
                if (!vis[j] && b[j] >= a[i]) {
                    vis[j] = 1;
                    cnt++;
                    break;
                }
            if (j != n)
                continue;
            for (j = n - 1; j >= 0; j--) {
                if (!vis[j]) {
                    vis[j] = 1;
                    a[i] -= b[j];
                    i--;
                    break;
                }
            }
        }
        if (cnt == 4) {
            printf("YES");
            int num = 0;
            for (int i = 0; i < n; i++)
                if (!vis[i])
                    num += b[i];
            printf(" %d\n", num);
        }
        else
            printf("NO\n");
    }
    return 0;
}
时间: 2024-11-17 16:13:48

acdream 1073(贪心)的相关文章

acdream 1717(贪心)

题意: Problem Description ACdream王国有一条贯穿整个王国的高速公路,一天,你要驾驶着一辆油箱容量为P的车从高速公路的一头驶向另一头,总路程为L千米,每单位体积的汽油可维持行驶W千米,显然路途遥远~总有不够油的情况,所以就要加油~! 再高速公路上总共有N个加油站,但是由于是不同人开的,因此定价也参差不齐. 现在你知道每个加油站的位置,以及每个加油站的单价,问你最少需要多少钱才能到达另一头? Input 多组数据,每组数据首先是四个整数,P(1<=P<=100),L(1

acdream 1716(贪心)

题意: Problem Description 在ACdream王国中,有一条母亲河,这条母亲河为王国人民提供了各种生活用水.在河边共住着n户人家,每户人家的位置为x[i].由于经济发展需要,ACdream决定在这条母亲河上建立一个水力发电站,经过勘测,这个水力发电站只可以建立在区间[a,b]的某一个地方x0.为了减少大家受到来此发电站的影响,希望min{|x[i]-x0| |0<=i<=n-1}最大,即使得距离发电站最近的人家与发电站的距离最大.若有多组答案,输出坐标较小的即可. Input

acdream 1212(贪心)

题意:有n个人,从1到n,编号越大职位越低,然后给出了第2到第n个人的上司的编号,每个人可以有一堆小弟但只能有一个上司.年底发奖金,每个人可以从上司那得到1000元或发给某个小弟1000元,问所有人能发的奖金和最大是多少,那些人得到了奖金. 题解:直接倒着遍历一遍,把人和他的上司标记掉算作一组,看有几组. #include <stdio.h> #include <string.h> const int N = 500005; int pa[N], n, flag[N]; int m

acdream 1224(贪心)

题意:有n个抢劫者抢劫了m块金子,然后第i个人平分xi/y块金子,但是会有除不尽的情况而金子不可再分,那么每个人都有一个不满意度fabs(xi / y - ki/m),ki是每个人实际分得的金子数量,要保证所有人的不满意度和最小,问ki应如何分配. 题解:如果可以除尽,ki就是xi * m / y,否则要把不满意度和再多分一块金子的不满意度的差值存起来,按从大到小排序,把多出来的金子数量num给前num个人多分一块. #include <cstdio> #include <cstring

ACdream 1073

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; bool cmp(int a,int b) { return a>b; } int main() { int i,n,exp[1024],a[10],ans,cnt,now; while(~scanf("%d",&n)) { memset(exp,0,sizeof(exp)); sc

acdream 1735 输油管道 贪心

输油管道 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acdream.info/problem?pid=1735 Description 平面上有n个油井,现在要建立一条主干线,用来把所有的油井产出的原油都输送出去,主干线是平行于x轴的一条直线,每个油井通过一条支线把原油输送到主干线上,现在给定n个油井在平面上的坐标,那么应该把主干线建在什么地方才能让所有的支干线的总长度最小呢? A的某一段完全重合,或者能够经过上下左右平移与折线A的

ACDream 1734 Can you make a water problem?(贪心)

Can you make a water problem? Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description Losanto want to make a water problem. But he have no idea….Then he thought a problem: A b

ACdream 1224 Robbers (贪心)

Robbers Special Judge Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Problem Description N robbers have robbed the bank. As the result of their crime they chanced to get M golden coins. Before the robbery the band ha

[ACdream 1212 New Year Bonus Grant]贪心

题意:员工之间形成一棵树,上级可以给下级发奖金,任何一个人最多可以给一个下级发,并且发了奖金后就不能接受奖金.求总共最多可以产生多少的奖金流动 思路:每次选择没有下级并且有上级的员工a,令它的上级为b,那么让b给a发奖金,之后把a和b从树中删掉,这样处理直到不存在这样的员工a.也就是说每次让叶子员工接受奖金.简单证明:对于最优情况,叶子和它的兄弟集合还有它的父亲一定有一个接受了奖金,否则可以选叶子接受从父亲发的奖金,这样比原来增加了1个奖金:假设父亲接受了奖金或者兄弟接受了奖金,那么换成自己接收